119

{}使用而不是字符串连接有什么好处吗?

来自 slf4j 的示例

logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

代替

logger.debug("Temperature set to"+ t + ". Old temperature was " + oldT);

我认为这是关于速度优化的,因为可以根据配置文件在运行时避免参数评估(和字符串连接)。但是只有两个参数是可能的,那么有时除了字符串连接之外别无选择。需要就这个问题发表意见。

4

6 回答 6

81

关于字符串连接性能的。如果您有密集的日志记录语句,这可能很重要。

(SLF4J 1.7 之前)但只有两个参数是可能的

因为绝大多数日志语句有 2 个或更少的参数,所以 SLF4J API 直到 1.6 版涵盖(仅)大部分用例。自 API 版本 1.7 起,API 设计者提供了带有可变参数的重载方法。

对于那些你需要超过 2 个并且你坚持使用 1.7 之前的 SLF4J 的情况,那么只需使用字符串连接或new Object[] { param1, param2, param3, ... }. 它们的数量应该足够少,以至于性能不那么重要。

于 2012-05-11T16:49:45.847 回答
52

短版:是的,它更快,代码更少!

字符串连接在不知道是否需要的情况下做了很多工作(从 log4j 已知的传统“启用调试”测试),如果可能的话应该避免,因为 {} 允许延迟 toString() 调用和字符串构造在确定事件是否需要捕获之后。通过让记录器格式化单个字符串,我认为代码变得更清晰。

您可以提供任意数量的参数。请注意,如果您使用旧版本的 sljf4j 并且有两个以上的参数{},则必须使用new Object[]{a,b,c,d}语法来传递数组。参见例如http://slf4j.org/apidocs/org/slf4j/Logger.html#debug(java.lang.String, java.lang.Object[])

关于速度:Ceki 不久前在其中一个列表上发布了一个基准。

于 2012-05-15T07:52:07.307 回答
8

由于 String 在 Java 中是不可变的,因此对于每一对连接,都必须将左右 String 复制到新的 String 中。所以,最好选择占位符。

于 2018-04-25T16:12:34.550 回答
3

另一种选择是String.format(). 我们在jcabi-log(围绕 slf4j 的静态实用程序包装器)中使用它。

Logger.debug(this, "some variable = %s", value);

它更易于维护和扩展。此外,它很容易翻译。

于 2012-10-05T06:36:49.457 回答
2

我认为从作者的角度来看,主要原因是减少字符串连接的开销。我刚刚阅读了记录器的文档,您可以找到以下文字:

/**
* <p>This form avoids superfluous string concatenation when the logger
* is disabled for the DEBUG level. However, this variant incurs the hidden
* (and relatively small) cost of creating an <code>Object[]</code> before 
  invoking the method,
* even if this logger is disabled for DEBUG. The variants taking
* {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two}
* arguments exist solely in order to avoid this hidden cost.</p>
*/
*
 * @param format    the format string
 * @param arguments a list of 3 or more arguments
 */
public void debug(String format, Object... arguments);
于 2018-09-12T21:59:46.830 回答
0

兼容日志记录对于应用程序开发非常重要,因为它会影响性能。

提到的不合规日志记录导致每次调用时都会调用冗余的toString()方法,并且会导致冗余的临时内存分配和 CPU 处理,如示例大规模测试执行中所示,我们可以在其中查看冗余分配的临时内存: 记忆

查看方法分析:
查看方法分析

注意:我是这篇博文的作者,日志记录对应用程序性能的影响。

于 2022-01-26T13:58:35.643 回答