基于字符串创建的slf4j和log4j之间的区别

时间:2013-10-09 11:28:44

标签: java log4j slf4j

如果我们写

,请在log4j中
**logger.debug("Processing trade with id: " + id + " symbol: " + symbol);**

它将在字符串池中创建String,但是当我们使用slf4j时,我们使用类似

的参数
**logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);**

那么这两个语句有什么区别,slf4j会在运行时创建String吗?

6 个答案:

答案 0 :(得分:21)

区别在于性能的提高,在log4j中,即使日志级别低于debug,每次评估行时字符串也会连接在一起,因此字符串将永远不会被使用。

slf4j,字符串和参数被传递给记录器,只有在实际使用日志消息时才会替换它们。

想象一下每隔几行使用调试语句的代码,当生产和调试被禁用时,这是一个永远不会被使用的大量字符串操作。

答案 1 :(得分:7)

我想说通过减少字符串concatenations来提高性能。

当你写这个

"Processing trade with id: " + id + " symbol: " + symbol

您正在手动创建打印字符串。

写作时

"Processing trade with id: {} and symbol : {} ", id, symbol
                    -------^id------------^symbol---------

在内部打印之前的第二种方式slf4j维护并再次生成带有连接的新字符串(没有检查源代码,可能是StringBuilder)。

{}称为占位符,并由您传递的args替换。

From docs of sl4j

  

当为DEBUG级别禁用记录器时,此表单可避免多余的字符串连接。但是,即使为DEBUG禁用了此记录器,此变量也会在调用方法之前产生隐藏(且相对较小)的创建Object []的成本。采用一个和两个参数的变体仅仅是为了避免这种隐藏成本。

阅读如何使用格式:How to use java.String.format in Scala?

答案 2 :(得分:5)

SLF4J基本上是一个抽象层。它不是日志记录实现。这意味着如果您正在编写库并使用SLF4J,则可以将该库提供给其他人使用,并且他们可以选择与SLF4J一起使用的日志实现,例如: log4j或Java日志API。它有助于防止项目依赖于大量日志API,因为它们使用依赖于它们的库。

答案 3 :(得分:2)

使用Log4j2 API,我们可以拥有 logger.info(“String:{} int:{}。”,“Hello,World”,10);

答案 4 :(得分:1)

  

那么这两个语句之间有什么区别,slf4j会   是否在朗姆酒时创建String?

无论您使用的是log4j还是sl4j,都会创建字符串。 sl4j提供便利的占位符。

答案 5 :(得分:0)

它是关于字符串连接的。第一行总是使String concat成为昂贵的操作,如果日志级别不匹配debug,则第二行不会连接。 我不确定只是假设,匹配日志级别第二个选项可以更好的性能,因为内部的StringBuilder使用。