使用
{}
代替字符串连接有什么优势吗?
来自 slf4j 的示例
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
而不是
logger.debug("Temperature set to"+ t + ". Old temperature was " + oldT);
我认为这与速度优化有关,因为根据配置文件,可以在运行时避免参数评估(和字符串连接)。但只有两个参数是可能的,那么有时除了字符串连接之外别无选择。需要对此问题的看法。
它是关于字符串连接性能的。如果您有密集的日志记录语句,这可能很重要。
(SLF4J 1.7之前)但只能使用两个参数
由于绝大多数日志记录语句都有 2 个或更少的参数,因此 SLF4J API 至版本 1.6 涵盖(仅)大多数用例。自 API 1.7 版本以来,API 设计者提供了带有可变参数参数的重载方法。
对于需要超过 2 个并且您受困于 1.7 之前的 SLF4J 的情况,则只需使用字符串连接或
new Object[] { param1, param2, param3, ... }
。它们的数量应该足够少,性能就不那么重要了。
简短版本:是的,速度更快,代码更少!
字符串连接在不知道是否需要的情况下做了很多工作(log4j 中已知的传统“启用调试”测试),并且应该尽可能避免,因为 {} 允许延迟 toString() 调用和字符串确定事件是否需要捕获后进行构建。在我看来,通过让记录器格式化一个single字符串,代码会变得更干净。
您可以提供任意数量的参数。请注意,如果您使用旧版本的 sljf4j 并且有两个以上的
{}
参数,则必须使用 new Object[]{a,b,c,d}
语法来传递数组。参见例如http://slf4j.org/apidocs/org/slf4j/Logger.html#debug(java.lang.String, java.lang.Object[]).
关于速度:Ceki 不久前在其中一个列表上发布了一个基准。
由于 String 在 Java 中是不可变的,因此对于每对串联,必须将左右 String 复制到新 String 中。所以,最好选择占位符。
另一种选择是
String.format()
。我们在 jcabi-log(围绕 slf4j 的静态实用程序包装器)中使用它。
Logger.debug(this, "some variable = %s", value);
它更易于维护和扩展。此外,它很容易翻译。
我认为从作者的角度来看,主要原因是为了减少字符串连接的开销。我刚刚阅读了logger的文档,你可以找到以下文字:
/**
* <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);
串联的成本很高,因此您希望仅在需要时才进行串联。通过使用
{}
,slf4j 仅在需要跟踪时才执行串联。在生产中,您可以将日志级别配置为 INFO,从而忽略所有调试跟踪。
这样的跟踪将连接字符串,即使跟踪将被忽略,这是浪费时间:
logger.debug("Temperature set to"+ t + ". Old temperature was " + oldT);
这样的痕迹将被免费忽略:
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
如果您有很多在生产中忽略的调试跟踪,那么使用
{}
肯定更好,因为它对性能没有影响。
合规日志记录对于应用程序开发非常重要,因为它会影响性能。
提到的不合规日志记录会在每次调用时导致冗余的 toString() 方法调用,并导致冗余的临时内存分配和 CPU 处理,如大规模测试执行示例所示,我们可以在其中采取查看冗余分配的临时内存:
查看方法分析:
注意:我是这篇博文的作者,记录对应用程序性能的影响。