我不熟悉 log4net 或 log.DebugFormat(...)。
但是伐木的成本实际上是在两个方面。
第一个是日志调用,第二个是日志信息的实际持久化。
当实际上不需要记录时,守卫有助于将记录调用减少到最低限度。它往往非常快,因为它只不过是一个方法调用和两个标量的比较。
但是,当您不使用守卫时,成本很可能成为创建实际日志记录参数的代价。
例如,在 log4j 中,这是一个常见的习惯用法:
log.debug("Runtime error. Order #" + order.getOrderNo() + " is not posted.");
在这里,成本是对生成消息的字符串表达式的实际评估。这是因为无论日志记录级别如何,都会创建该表达式和结果字符串。想象一下,如果你有类似的东西:
log.debug("Something wrong with this list: " + longListOfData);
这可能会创建一个大而昂贵的字符串变量,如果没有为 DEBUG 设置日志级别,那么它只会被浪费。
守卫:
if (log.isDebug()) {
log.debug(...);
}
消除这个问题,因为 isDebug 调用很便宜,尤其是与参数的实际创建相比。
在我的代码中,我编写了一个用于日志记录的包装器,我可以像这样创建日志:
log.debug("Runtime error. Order # {0} is not posted.", order.getOrderNo());
这是一个很好的妥协。这依赖于 Java 可变参数,我的代码检查日志记录级别,然后适当地格式化消息。这几乎和守卫一样快,但写起来更干净。
现在,log.DebugFormat 可能会做类似的事情,我不知道。
当然,最重要的是日志记录的实际成本(到屏幕、到文件、到套接字等)。但这只是您需要接受的成本。我的最佳实践是,在实际可行的情况下,将实际的日志消息路由到一个队列,然后使用单独的线程将其收割并输出到正确的通道。至少,这有助于使日志与主计算保持一致,但它本身就有费用和复杂性。