如果我们写
,请在log4j中**logger.debug("Processing trade with id: " + id + " symbol: " + symbol);**
它将在字符串池中创建String,但是当我们使用slf4j时,我们使用类似
的参数**logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);**
那么这两个语句有什么区别,slf4j会在运行时创建String吗?
答案 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替换。
当为DEBUG级别禁用记录器时,此表单可避免多余的字符串连接。但是,即使为DEBUG禁用了此记录器,此变量也会在调用方法之前产生隐藏(且相对较小)的创建Object []的成本。采用一个和两个参数的变体仅仅是为了避免这种隐藏成本。
答案 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使用。