50

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

为了让自己更清楚:我很清楚每个人的差异,只是我不知道是否值得实际编写 StringBuilder 代码,因为它的可读性较低,而且当它的所谓较慢的表亲 String 类自动转换为无论如何编译过程。

4

4 回答 4

118

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

一般使用 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();

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

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

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

于 2013-02-18T00:37:13.560 回答
3

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

如果你要写这段代码,但还没有写,那就写你更清楚的东西,如果有必要,看看它是否是一个瓶颈。

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

于 2013-02-18T00:20:34.123 回答
2

这取决于具体情况,但 StringBuilder 被认为要快一些。如果您在循环内进行连接,那么我建议您使用 StringBuilder。

无论如何,我建议您对您的代码进行分析和基准测试(如果您正在执行如此大规模的附加操作)。

不过要小心:StringBuilder 的实例是可变的,不能在线程之间共享(除非你真的知道自己在做什么。)而不是不可变的 String。

于 2013-02-18T00:09:38.373 回答
0

我可能误解了你的问题,但 StringBuilder 附加字符串时更快。所以,是的,如果您要附加“数十万行”,那么您绝对应该使用 StringBuilder (如果您正在运行多线程应用程序,则使用 StringBuffer )。

(评论中更详尽的答案)

于 2013-02-18T00:07:34.257 回答