Java:String concat vs StringBuilder - 优化了,所以我该怎么办?

在这个答案中,它说(暗示)字符串连接无论如何都被优化为StringBuilder操作,那么当我编写代码时,有什么理由在源代码中编写StringBuilder代码?请注意,我的用例与OP的问题不同,因为我连接/附加了数十万行。

为了让自己更清楚:我很清楚每个的区别,只是我不知道它是否值得实际编写StringBuilder代码,因为它的可读性较差,并且当它所谓的较慢的表亲String类在编译过程中自动转换时。


答案 1

我认为 vs 的使用实际上取决于您使用它的上下文。StringBuilder+

通常使用JDK 1.6及更高版本的编译器会自动使用.StringBuilder

String one = "abc";
String two = "xyz";
String three = one + two;

这将编译为:String three

String three = new StringBuilder().append(one).append(two).toString();

这非常有用,为我们节省了一些运行时。然而,这个过程并不总是最佳的。举个例子:

String out = "";
for( int i = 0; i < 10000 ; i++ ) {
    out = out + i;
}
return out;

如果我们编译为字节码,然后反编译生成的字节码,我们得到如下结果:

String out = "";
for( int i = 0; i < 10000; i++ ) {
    out = new StringBuilder().append(out).append(i).toString();
}
return out;

编译器优化了内部循环,但肯定没有进行最佳优化。为了改进我们的代码,我们可以使用:

StringBuilder out = new StringBuilder();
for( int i = 0 ; i < 10000; i++ ) {
    out.append(i);
}
return out.toString();

现在,这比编译器生成的代码更优化,因此在需要高效代码的情况下,肯定需要使用 / 类编写代码。当前的编译器并不擅长在循环中处理串联字符串,但是将来可能会改变。StringBuilderStringBuffer

您需要仔细查看需要手动应用的位置,并尝试在不降低代码可读性的地方使用它。StringBuilder

注意:我使用JDK 1.6编译代码,并使用该程序反编译代码,这会吐出字节码。它相当容易解释,并且在尝试优化代码时通常是一个有用的参考。编译器确实会在幕后更改您的代码,因此查看它的作用总是很有趣的!javap


答案 2

你问题中的关键短语是“据说更慢”。您需要确定这是否确实是瓶颈,然后查看哪个更快。

如果您即将编写此代码,但尚未编写它,请编写对您来说更清晰的内容,然后如果需要,请查看它是否是瓶颈。

虽然使用你认为更像更快的代码是有意义的,但如果两者都具有同等的可读性,那么实际上当你不需要的时候花时间找出哪个更快是浪费时间。可读性高于性能,直到性能不可接受。