Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测井性能和操作员<&书信电报; 我对开源C++应用做出贡献。在该应用程序中,所有日志记录都是使用诸如 if (Debug) std::cout << "MyClass | my debug message" << MyExpensiveStringConvertion() << std::endl; if(Debug)std::cout_C++_Logging - Fatal编程技术网

测井性能和操作员<&书信电报; 我对开源C++应用做出贡献。在该应用程序中,所有日志记录都是使用诸如 if (Debug) std::cout << "MyClass | my debug message" << MyExpensiveStringConvertion() << std::endl; if(Debug)std::cout

测井性能和操作员<&书信电报; 我对开源C++应用做出贡献。在该应用程序中,所有日志记录都是使用诸如 if (Debug) std::cout << "MyClass | my debug message" << MyExpensiveStringConvertion() << std::endl; if(Debug)std::cout,c++,logging,C++,Logging,如果输出操作前面没有条件,关键问题是所有参数都在求值。短路实际的输出操作很容易(只需确保Log(debug)返回一个状态为std::ios_base::failbit的流),但评估所有参数往往会涉及到您不希望在记录期间花费的开销。当然,您可以使用以下方法修复日志记录的符号 #define LOG(level) if (doDebug(level)) Log(level) 。。。然后使用 LOG(debug) << "MyClass | my debug message" <&

如果输出操作前面没有条件,关键问题是所有参数都在求值。短路实际的输出操作很容易(只需确保
Log(debug)
返回一个状态为
std::ios_base::failbit
的流),但评估所有参数往往会涉及到您不希望在记录期间花费的开销。当然,您可以使用以下方法修复日志记录的符号

#define LOG(level) if (doDebug(level)) Log(level)
。。。然后使用

LOG(debug) << "MyClass | my debug message" << MyExpensiveStringConversion();

LOG(debug)如果你希望你的应用程序使用大量的日志记录,那么第一个选项将产生很大的不同。
否则,这并不重要

您可以将log函数包装在宏中,以便在编译时出于基准测试的目的轻松禁用它

#ifdef LOG_ENABLED
    #define LOGSTR(x) do { \
                     debug && Log(debug) << x << MyExpensiveStringConvertion() \
         } while (0)
#else
    #define LOGSTR(x) (void)0
#endif
#已启用ifdef日志
#定义LOGSTR(x)do{\

debug&&Log(debug)这是正确的。针对布尔值(
if(debug)
)的简单测试很便宜,并且将跳过非限定的
Log(debug)
语句所需的昂贵字符串“conversion”。代码基本上相当于:

test some_register, Debug
jne  skip_the_debug_crap
-- potentially lots of code here --

skip_the_debug_crap:
carry on...
与:

call ExpensiveStringConversion
call operator << with result (maybe, depends on what class is returned by conversion)
call operator << for whatever class Log(debug) evaluates to (with test for debug in callee)
clean up after function call
carry on...
呼叫费用投资转换

呼叫接线员多亏了我所知道的所有海报,我能回答自己的问题

if(Debug)看起来更有效,但大多数日志框架的实现方式似乎都包括了其他海报中提到的技巧

例如,EasyLogg++有DLOG和DCLOG,它们都实现为 #如果(\u ELPP\u DEBUG\u LOG)阻塞(级别,VA\u ARGS),则定义DCLOG(级别,…)

glog(googlelogging)还有一个DLOG,它既可以检查全局变量,也可以在编译时禁用 """ glog提供的条件日志宏(例如,CHECK、LOG_IF、VLOG等)是仔细实现的,当条件为false时,不会执行右侧表达式。因此,以下检查可能不会牺牲应用程序的性能


检查(obj.ok)是否正确,事实是
被称为比评估
更重要。大多数日志框架都是垃圾。这就是为什么我写了自己的日志框架。@doc我也是,尽管我在生产中遇到了恼人的问题,可能一个合适的框架已经解决了(例如,日志滚动失败,因为有人克隆了进程,并在我的日志文件上留下了一个孤立的句柄)最好在
#else
分支中定义
#define LOGSTR(x)(void)0
。否则像这样的代码
if(something)LOGSTR(“blahblah”)
可能无法预测(在大多数情况下会给您带来编译错误).+1。@doc
do{}while(0)
是最健壮的方法,根据有用的注释进行了修复。这听起来是个好主意,但我被期望在大多数记录器框架中都能使用这种性能技巧,不是吗?
call ExpensiveStringConversion
call operator << with result (maybe, depends on what class is returned by conversion)
call operator << for whatever class Log(debug) evaluates to (with test for debug in callee)
clean up after function call
carry on...