String.format() 和字符串拼接哪个性能更好?

19

这两个惯用语在性能方面有区别吗?

String firstStr = "Hello ";
String secStr   = "world";
String third = firstStr +  secStr;

String firstStr = "Hello ";
String secStr   = "world";
String third = String.format("%s%s",firstStr , secStr);

我知道使用加号运算符进行字符串拼接会影响性能,特别是在操作频繁的情况下,但是String.format()呢?它是一样的还是可以提高性能?


将常量字符串连接起来,第一个示例将被编译器明显优化,因为结果字符串是一个常量,不应该对性能产生任何影响。 - Smutje
2
@Smutje 第三个字符串不是常量。如果前两个是“final”,它将是一个常量。 - Sotirios Delimanolis
对,我太习惯于将本地变量默认/尽可能设置为final了,以至于我差点忘记这不是强制要求的。 :-) - Smutje
1
它们是两种不同的动物。连接更快(编译器大多数时候都足够聪明,可以自行优化,你只需要在循环中等情况下使用 StringBuilder)。格式化速度较慢,但功能更强大(例如,你可以通过正确设置宽度来调整并打印表格数据等) 。 - Anthony Accioly
3个回答

19

第二种方法会更慢(如果你查看String.format()的源代码,你会知道为什么)。这只是因为String.format()执行的代码比简单连接多得多。最终,两个代码版本都创建了3个String实例。有其他原因,与性能无关,需要使用String.format(),正如其他人已经指出的那样。


8
首先,我要声明一下,不要过早优化。除非你相当确定这将是程序中的热点,否则只需选择最适合你的程序的结构即可。
但是如果你相当确定,并且想对连接操作有很好的控制,那么直接使用StringBuilder即可。这就是内置的连接操作所做的事情,而且没有理由认为它会很慢。只要你保持同一个StringBuilder并继续追加它,而不是冒险创建几个(这些必须用之前创建的数据进行“初始化”),你就可以获得正确的O(n)性能。特别是如果你确保使用正确的容量初始化StringBuilder。
另外,正如上面提到的,StringBuilder是内置连接操作所使用的,因此如果只是将所有连接“内联” - 也就是说,使用A + B + C + D,而不是像e = A + B然后f = C + D然后e + f(这样,整个操作都使用相同的StringBuilder并追加到其中) - 那么没有理由认为它会很慢。
编辑:针对您的评论,我要说String.format始终较慢。即使它以最佳方式追加,它也无法比StringBuilder(因此也包括连接操作)更快地完成它,但它还必须创建Formatter对象,解析输入字符串等等。因此,它还有更多的工作要做,但它仍然无法更快地执行基本操作。
此外,如果您在内部查看Formatter的工作方式,您会发现它(默认情况下)也使用StringBuilder,就像连接操作一样。因此,它执行完全相同的基本操作-即用你给它的字符串填充StringBuilder。只是它用了更迂回的方式。

谢谢,你说得对。在构建字符串时,StringBuilder是最佳选择,尽管我的问题更多地是比较描述中列出的两个习惯用语。 - Leo

1

2
如果您要这样做,请简要介绍一下链接答案的内容。 - Sotirios Delimanolis
2
谢谢!我的问题更多关于性能方面,而不是使用i18n的能力。 - Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接