我参与了一个开源的c ++应用程序.在该应用程序中,所有日志记录都使用诸如
if (Debug) std::cout << "MyClass | my debug message" << MyExpensiveStringConvertion() << std::endl;
Run Code Online (Sandbox Code Playgroud)
用于使用更高级的日志记录框架(在其他语言中)我建议使用一个现有的框架,如boost,easylogginppp,无论是自动格式化还是可以在运行时配置.
但我回答说使用"if(Debug)"在写入时几乎没有开销
Log(debug) << "MyClass | my debug message" << MyExpensiveStringConvertion()
Run Code Online (Sandbox Code Playgroud)
在禁用日志记录时,需要计算<<运算符和MyExpensiveStringConvertion()事件.这个论点是否正确?如果它是正确的,我们应该关心吗?看起来大多数日志框架都以这种方式工作,显然大多数开发人员都不关心
更新:我理解如果(Debug)表单只需要一个简单的bool测试,但我期望日志框架实现各种技巧以降低成本,如"#define LOG(level)if(doDebug(level))Log(level) "DietmarKühl提到.
在输出操作之前没有条件的关键问题是正在评估所有参数。短路实际的输出操作很容易(只需确保Log(debug)返回std::ios_base::failbit状态已设置的流),但是评估所有参数往往会导致您在日志记录期间不希望花费的开销。当然,您可以使用以下方法修复日志记录的表示法:
#define LOG(level) if (doDebug(level)) Log(level)
Run Code Online (Sandbox Code Playgroud)
...然后使用
LOG(debug) << "MyClass | my debug message" << MyExpensiveStringConversion();
Run Code Online (Sandbox Code Playgroud)
感谢所有我知道的海报能够回答我自己的问题。
if(调试)看起来更有效,但大多数日志记录框架似乎都是以这样的方式实现的,它们实际上包含其他海报提到的技巧
例如 easylogging++ 有 DLOG 和 DCLOG,它们都实现为 #define DCLOG(LEVEL, ...) if (_ELPP_DEBUG_LOG) CLOG(LEVEL, VA_ARGS )
glog(谷歌日志记录)也有一个 DLOG,它也可以检查全局变量或可以在编译时禁用。Glog 文档还说“”“glog 提供的条件日志记录宏(例如 CHECK、LOG_IF、VLOG 等)经过仔细实现,当条件为 false 时,不会执行右侧表达式。因此,以下检查可能不会牺牲应用程序的性能。
检查(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow(); ”“”
我猜boostlogging也实现了类似的性能技巧