slf4j和log4j在字符串创建基础上的区别

2022-09-02 03:13:34

在 log4j 中,如果我们写

**logger.debug("Processing trade with id: " + id + " symbol: " + symbol);**

它将在字符串池中创建字符串,但是当我们使用slf4j时,我们使用基于这样的参数

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

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


答案 1

不同之处在于性能的提高,在log4j中,每次评估行时,即使日志级别低于debible,字符串也会串联,因此永远不会使用该字符串。

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

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


答案 2

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

当你写这个

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

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

当你写作时

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

在第二种方式打印之前内部维护并生成一个新的字符串,再次与串联(没有检查源代码,可能是一个)。slf4jStringBuilder

被调用为占位符,并由您传递的参数替换。{}

来自 sl4j 的文档

此形式可避免在 DEBUG 级别禁用记录器时出现多余的字符串串联。但是,此变体在调用方法之前会产生创建 Object[] 的隐藏(且相对较小)成本,即使此记录器在 DEBUG 中禁用也是如此。采用一个和两个参数的变体只是为了避免这种隐性成本而存在的。

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


推荐