Java:String concat vs StringBuilder – 优化,我该怎么办?

在这个答案中 ,它表示(意味着)string连接已经优化到StringBuilder操作中,所以当我编写代码时,是否有任何理由在源代码中编写StringBuilder代码? 请注意,我的用例与OP的问题不同,因为我连接/追加了成千上万行。

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

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

通常使用JDK 1.6及以上版本,编译器将使用StringBuilder自动将string连接在一起。

 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类编写代码。 目前的编译器并不擅长处理循环中的string连接,但是这可能会在将来改变。

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

注意:我使用JDK 1.6编译代码,并使用javap程序反编译代码,该程序会分配字节码。 这是相当容易解释,而且往往是一个有用的参考,当试图优化代码。 编译器确实改变了你在后台的代码,所以总是看到它的作用。

在你的问题中的关键短语是“应该慢”。 你需要确定这是否确实是一个瓶颈,然后看哪个更快。

如果你准备写这些代码,但是还没有写出代码,那么写一些更清楚的代码,然后如果有必要的话,看看它是否是一个瓶颈。

尽pipe使用代码更合理,但如果两者都具有相同的可读性,那么在没有必要的情况下真正花点时间找出更快的代码是浪费时间的。 可读性高于性能,直到性能不可接受。

这取决于案件,但StringBuilder被认为是有点快。 如果你正在做一个循环内的串联,那么我build议你使用StringBuilder。

无论如何,我build议你对你的代码进行configuration和基准testing(如果你正在做这么大的附加)。

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

我可能误解了你的问题,但StringBuilder在追加string时速度更快。 所以,是的,如果你正在追加“成千上万行”,你一定要使用StringBuilder(或者如果你正在运行一个multithreading的应用程序,则使用StringBuffer)。

(在评论中更彻底的回答)