如果isDebugEnabled()包含对debug()的调用:一个好的策略?

Che*_*hei 23 java performance logging coding-style

我们的团队有像日志这样做的政策

if (LOGGER.isDebugEnabled()) {  
  LOGGER.debug("model[" + model + "]");
}
Run Code Online (Sandbox Code Playgroud)

而不是像这样简单地调用日志记录方法:

LOGGER.debug("model[" + model + "]");
Run Code Online (Sandbox Code Playgroud)

这种做法能够带来一些性能提升,但另一方面它使代码库更加复杂.我们的应用程序没有性能问题,可能永远不会,引入策略的论点只是它是一个很好的做法,因此每次我们进行日志记录时都应该使用它.

你认为这是一个好政策吗?

小智 27

您应该使用SLF4J并使log4j成为您的实现.使用SLF4J,您可以isDebugEnabled()通过使用参数化消息完全消除.

请参阅slf4j FAQ中有关日志记录性能部分

以下两行将产生完全相同的输出.但是,在禁用日志记录语句的情况下,第二种形式的性能将比第一种形式的性能至少提高30倍.

logger.debug("The new entry is " + entry + ".");

logger.debug("The new entry is {}.", entry);

  • 当参数构建"入口"成本高时,字符串格式化没有帮助.例如,考虑一些`logger.debug("新条目是{}.",getEntry());`并且你不知道`getEntry()`有多贵. (3认同)

Jon*_*eet 19

对于那些正在构建的日志字符串实际上会显着影响性能的场合,这是一个很好的策略.这可能有两个原因:

  • 很多工作需要用于构建字符串(例如,它必须进行查找,或者从很多非常小的部分构建一个非常大的字符串)
  • 它处于一个没有做太多其他工作的循环中(但经常被调用),所以构建一个简单的日志字符串所花费的时间比例更高

它不应该是一个统一的规则,我希望这两种情况都相对罕见.

当然,我们真正想要的是能够说,"调用调试方法,传入一个不是调试字符串本身的参数,但是知道如何构建调试字符串的东西,当且仅当它是必要." 如果没有简洁的闭包,这在Java中会很难看.(即使在具有lambda表达式形式的闭包的语言中,捕获相关变量在某些情况下也可能很重要,具体取决于语言处理捕获的方式.)

  • SLF在日志方法中是否有字符串格式化选项? (2认同)

Che*_*hei 8

我同意Michael A. Jackson的名言:

程序优化的第一条规则:不要这样做.

程序优化的第二条规则 - 仅限专家:不要这样做.

我认为在大多数情况下,如果不确定性能增益是否显着/重要,则不值得使代码库更复杂.

我知道性能的提高,但我认为个别程序员有责任决定是否值得在特定情况下添加额外的代码行.在大多数情况下,额外的线条只会增加复杂性而在性能方面没有任何显着的增益.

  • 很明显,如果作者问过这个问题,那么就是要求他进行优化.即,当您被要求优化一段代码时,您不会回复上述两个引号.了解您的来源,但在这种情况下无济于事. (2认同)