【问题标题】:Using .append(string1 + string 2) vs .append(string1).append(string2)使用 .append(string1 + string 2) 与 .append(string1).append(string2)
【发布时间】:2014-01-08 12:16:43
【问题描述】:

我想知道是否有人可以回答我使用 StringBuilder 对象在 java 中哪一个语句会执行得更好:

使用

.append(string1 + string 2) 

对

.append(string1).append(string2)

【问题讨论】:

  • 我会选择第二个选项,因为第一个选项很可能会创建一个中间(不必要的)字符串
  • 如果两个字符串都是编译时常量,使用+;编译器将在编译时连接。否则,使用两个追加。

标签: java append stringbuilder string-concatenation


【解决方案1】:

第二个选项几乎肯定会更好(假设存在任何明显的性能差异)。当你写像

string1 + string2

内部翻译成

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

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

【讨论】:

    【解决方案2】:

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

    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())。

    【讨论】:

      【解决方案3】:

      第一个打字更快,在许多情况下更容易阅读。

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

      但是,这种字符串连接不太可能成为您系统的瓶颈!如果性能有问题,则需要进行概要分析。 编译器不同。而改进算法通常比这种微优化产生的影响要大得多。

      不要过早优化!真的!太诱人了,太浪费时间了。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-10
          • 2014-09-09
          • 1970-01-01
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          相关资源
          最近更新 更多