字符串连接的性能有多重要?

How performance heavy is String concatenation?

以下情况:我有很多日志语句,应该只在调试模式下执行。

关于如何实现这个,我有两个选择:

一个

public void log(String message){
    if(debug) doLog(message);
}

还有很多这样的陈述:

log(something.toString() + "somelogmessage");

B

public void log(message){
    doLog(message);
}

还有很多这样的陈述:

if(debug) log(something.toString() + "somelogmessage");

虽然 A 更好读并且生成的代码更少,但如果 debug 为 false,则 B 避免了字符串连接。

是否值得为提高性能而编写这些额外的样板代码? 或者它们是否相等(例如,由于编译器优化)?

我的意思是从技术上讲,选项 B 会稍微快一些,因为它不会在任何地方都考虑条件,但对于像这样小的东西,我肯定会建议使用选项 A。开销量很小它可以忽略不计,而且不值得为你必须在所有地方抛出的条件添加代码。

如果是 for 循环或一些真正繁重的代码,我会使用调试检查。

如果只是几个连接,我不会担心。

您可以提高性能并避免多余的串联,例如,在检查调试级别后在日志实现中使用 PrintStream format method

你也可以看看SLF4J。它有像 debug(String format, Object... objs) 这样的方法来防止连接。它还具有 isDebugEnabled() 这在您必须进行复杂登录时非常有用。

几个连接不会成为大问题,但您应该考虑向日志添加新方法API或使用 SLF4J 进行一些实现(例如 logback)

正如其他人所提到的(并且您已经通过标签确认),这是一个微优化,在绝大多数情况下可能无关紧要。但是,如果您希望在不弄乱代码的情况下避免连接,则可以添加一个接受两个参数的重载:

public void log(Object prefix, String message){
    if(debug) doLog(prefix.toString() + message);
}

然后调用

log(something, "somelogmessage");

如果您的消息可以由多个值组成,您可以改用可变参数:

public void log(String... values){
    if(debug) doLog(String.join("", values));
}

虽然在这种情况下性能优势更值得怀疑。