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

时间:2009-03-17 09:07:12

标签: java performance logging coding-style

我们的团队有像

这样的日志记录政策
if (LOGGER.isDebugEnabled()) {  
  LOGGER.debug("model[" + model + "]");
}

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

LOGGER.debug("model[" + model + "]");

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

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

6 个答案:

答案 0 :(得分:26)

您应该使用 SLF4J 并使 log4j 实施。使用 SLF4J ,您可以使用参数化消息完全消除isDebugEnabled()

请参阅section about logging performance in the slf4j FAQ

  

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

     

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

     

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

答案 1 :(得分:18)

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

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

它不应该是一条全面的规则,我希望这两种情况都相对罕见。

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

答案 2 :(得分:7)

我同意Michael A. Jackson的着名引语:

  

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

     

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

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

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

答案 3 :(得分:2)

我无法在线找到参考资料(也许是我在书中读到的),但有一个BIOS调用的例子,它在屏幕上写了一个字符串。

将字符串写入屏幕的代码检查以确保String不会离开屏幕,然后调用函数将字符写入屏幕。

将字符写入屏幕的函数已经过检查,以确保字符不会从屏幕上删除。

从将角色写入屏幕的功能中删除检查代码,可以大大提高速度。那是因为打印每个角色经常发生。他们还提供了一种方法,可以在呼叫前未检查屏幕位置时检查案例。

因此,如果您可以在较高级别进行检查并避免在较低级别进行检查,则可以显着加快速度。

在您提供的情况下,如果代码处于循环中或者有很多日志记录语句,那么将会有明显的好处:

  • 删除字符串创建(以及关联的GC)
  • 减少if语句的数量(虽然hotspote很可能会优化它们)。

我会说,一般情况下,如果有一个简单的解决方法,你不应该添加任何已知成本高昂的东西。这显然属于这种情况 - 添加if语句并不难,后来加入是一种痛苦,它提供了明确的速度/内存改进。

我认为这与过早优化之间的区别在于,众所周知这种情况总是很昂贵,所以问题归结为你想要添加到程序中的累积成本吗?成本几乎是不变的,并且在编写代码时就知道了。

答案 4 :(得分:1)

我认为在编写日志消息之前先调用isDebugEnabled()。 比以后您可以轻松更新日志消息。 我们使用以下代码使日志消息更加灵活。

if (LOGGER.isDebugEnabled()) {  
  String msg = "A Message {0} you can put {1} differet Objects in {2}"; //$NON-NLS-1$
  Object[] args = new Object[] {file1.toString(),new Integer(23),anObject};
  LOGGER.debug(MessageFormat.format(msg,args));
}

当你没有if语句时,你会浪费时间。请记住......您的项目会变得更大,也会记录您的日志消息。

记录消息不应该减慢你的代码!

答案 5 :(得分:0)

如果已经知道“模型”,那么记录它并不是那么昂贵。 但是,如果“模型”应仅用于记录,如下所示,简单性可能会受到影响。

LOGGER.debug("model[" + proxy.getModel() + "]");