+运算符何时比StringBuilder更快?

时间:2014-08-25 18:49:41

标签: java

过去,我一直认为在构建包含变量的字符串时应使用StringBuilderappend(String),而不是string += split[i]。在什么情况下这是准确的?我问,因为通常,如果我要写下面的内容:

String[] split = args; // command line arguments or whatever
String myString = "";
for (int i = 0; i < split.length; i++) {
    myString += split[i];
}

我的IDE告诉我应该转换为使用StringBuilder。但是,写下这样的东西:

StringBuilder build = new StringBuilder();
build.append("the ").append(build.toString()).append(" is bad").append(randomvar);
build.toString();

当我应该使用String时,IntelliJ实际上使用StringBuilder列为性能问题。它被列为性能问题这一事实表明它实际上可能会导致问题,而不是只是稍微慢一点。

我注意到第一个例子是一个循环,第二个例子是没有 - 是一个建议用于大量连接的StringBuilder但是正常连接对于非循环情况更好(这也意味着在一个循环中运算符{会使用{1}},而在循环之外它可能是+= - 是+ =问题而不是+?)

4 个答案:

答案 0 :(得分:9)

字符串连接在后台转换为对StringBuilder.append()的调用。

字符串文字串联(或至少可以)转换为单个字符串文字。

你可能在循环中使用了一个String变量(不仅仅是两个文字),因此Java不能用文字替换它;它必须使用StringBuilder。这就是为什么在循环中进行String连接应该使用单个StringBuilder完成的原因,否则Java会在每次循环迭代时最终创建另一个StringBuilder实例。

另一方面,这样的事情:

String animals = "cats " + "dogs " + "lizards ";

使用单个字符串文字将(或可以)替换(由Java,而不是您),因此使用StringBuilder实际上会适得其反。

答案 1 :(得分:3)

从java 1.5开始,String +运算符被转换为对StringBuilder的调用。

在你的例子中,循环应该更慢,因为+运算符每次循环都会创建一个新的StringBuilder实例。

答案 2 :(得分:1)

编译器实际上会在编译之前将它们都转换为相同的形式,因此两者都不会导致任何性能差异。在这种情况下,您希望使用最短且最易读的方法。

  

“实现可以选择执行转换和连接   在一步中避免创建然后丢弃中间体   字符串对象。增加重复字符串的性能   连接,Java编译器可以使用StringBuffer类或a   类似的技术减少了中间String对象的数量   通过评估表达式创建的。

     

对于原始类型,实现也可以优化掉   通过直接从基元转换来创建包装器对象   键入字符串。“

来源:http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2

答案 3 :(得分:0)

对于小的concats,你可以使用+运算符,没有问题。当我们要连接大字符串时会指示StringBuffer,因此使用此类可以节省内存和处理器的时间。

您可以尝试使用+运算符连接100万个单词,并使用StringBuffer运行相同的teste,以便自己查看不同的单词。