使用.append(string1 + string 2)vs .append(string1).append(string2)

时间:2013-12-19 19:22:45

标签: java append stringbuilder string-concatenation

我想知道是否有人能够回答这些陈述中的哪一个在使用StringBuilder对象的java中表现更好:

使用

.append(string1 + string 2) 

vs

.append(string1).append(string2)

4 个答案:

答案 0 :(得分:4)

第二种选择几乎肯定会更优越(假设任何 显着的性能差异)。当你写像

这样的东西
string1 + string2

它在内部翻译为

new StringBuilder(string1).append(string2).toString()

即。创建 new StringBuilder以连接字符串。您的第二个变体绕过了这个问题,因为它直接附加到现有的StringBuilder,避免创建新的。{/ p>

答案 1 :(得分:1)

我们可以看看每个选项的字节码:

public class Concat {
    private static String s1 = "foo";
    private static String s2 = "bar";

    public static String good() {
        StringBuilder b = new StringBuilder();
        b.append(s1).append(s2);
        return b.toString();
    }

    public static String bad() {
        StringBuilder b = new StringBuilder();
        b.append(s1 + s2);
        return b.toString();
    }
}

$javap -c Concat.class

 public static java.lang.String good();
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup           
       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       7: astore_0      
       8: aload_0       
       9: getstatic     #4                  // Field s1:Ljava/lang/String;
      12: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: getstatic     #6                  // Field s2:Ljava/lang/String;
      18: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: pop           
      22: aload_0       
      23: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: areturn       

  public static java.lang.String bad();
    Code:
       0: new           #2                  // class java/lang/StringBuilder
       3: dup           
       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       7: astore_0      
       8: aload_0       
       9: new           #2                  // class java/lang/StringBuilder
      12: dup           
      13: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
      16: getstatic     #4                  // Field s1:Ljava/lang/String;
      19: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: getstatic     #6                  // Field s2:Ljava/lang/String;
      25: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      34: pop           
      35: aload_0       
      36: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      39: areturn

您的第一个选项实际上变为append(new StringBuilder().append(s1).append(s2).toString())

答案 2 :(得分:0)

第一个键入的速度更快,在许多情况下更容易阅读。

第二个可能稍微好一点(根据Jeffrey的字节码和arshajii的解释)。

但是,这种字符串连接不太可能成为系统中的瓶颈!如果性能有问题,则需要进行配置。 编译器不同。改进算法通常比这种微优化具有更多,更大的影响。

不要在必要之前进行优化!真!这太诱人了,浪费时间。

答案 3 :(得分:0)

可以合理地预期,编译器的未来改进将使两个替代方案生成相同的代码。