+ =比concat更有效吗?

时间:2010-12-01 09:45:54

标签: java string string-concatenation

我一直在阅读我的团队中其他开发人员生成的代码,他们似乎赞成使用+=进行字符串连接,而我更喜欢使用.concat(),因为它更容易阅读。

我正在尝试准备一个论据,为什么使用.concat()更好,我想知道,两者之间的效率有什么不同吗?

我们应该选择哪个选项?

public class Stuff {

    public static void main(String[] args) {

        String hello = "hello ";
        hello += "world";
        System.out.println(hello);

        String helloConcat = "hello ".concat("world");
        System.out.println(helloConcat);
    }
}

7 个答案:

答案 0 :(得分:10)

没关系。现代Java编译器,JVM和JIT将以这样的方式优化您的代码,使差异可能很小。您应该努力编写更易读和可维护的代码。

答案 1 :(得分:9)

由于String在java中是不可变的,因此当您执行++=concat(String)时,会生成一个新的String。 String越大,所需的时间越长 - 复制的次数越多,产生的垃圾就越多。

今天的java编译器优化了你的字符串连接以使其最佳,例如

System.out.println("x:"+x+" y:"+y);

编译器将其生成为:

System.out.println((new StringBuilder()).append("x:").append(x).append(" y:").append(y).toString());

我的建议是编写更易于维护和阅读的代码。

此链接显示StringBuilder vs StringBuffer vs String.concat - done right

的效果

答案 2 :(得分:5)

我同意@darioo和其他大多数答案。始终首先考虑可读性(和可维护性)。 (对于像这样的简单情况,现代JIT编译器应该没有麻烦。)

然而,这是与您的程序对应的字节码。 (请注意,+=方法会产生StringBuilder,这通常是构造字符串时的首选方法。)

// String hello = "hello";
0: ldc #2; //String hello 
2: astore_1

// hello += "world";
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method StringBuilder."<init>"
10: aload_1
11: invokevirtual #5; //Method StringBuilder.append
14: ldc #6; //String world
16: invokevirtual #5; //Method StringBuilder.append
19: invokevirtual #7; //Method StringBuilder.toString

// System.out.println(hello);
22: astore_1
23: getstatic #8; //Field System.out
26: aload_1
27: invokevirtual #9; //Method PrintStream.println

// String helloConcat = "hello ".concat("world");
30: ldc #2; //String hello 
32: ldc #6; //String world
34: invokevirtual #10; //Method String.concat
37: astore_2

// System.out.println(helloConcat);
38: getstatic #8; //Field System.out
41: aload_2
42: invokevirtual #9; //Method PrintStream.println

45: return

答案 3 :(得分:3)

就可读性而言,我认为你错了。 +胜过.concat()。如果您使用的是+=,则可能需要考虑StringBuilder.append为循环保持相同的StringBuilder

在效果方面concat优于+。只要你只使用一个或两个。

如果是concat,您最终会创建一个String对象,其大小正确char[]。它就像你能得到的那样最佳。

对于+,javac会生成构造StringBuilder以执行追加然后转换为String的代码。从1.5创建:

  • A StringBuilder(废物)
  • char[](废物)
  • 的初始StringBuilder
  • 如果结果序列太长,则第二个更大char[](浪费)
  • 结果String
  • String的{​​{1}}。

但是,您很少看到char[]使用,因为它更难阅读。与其他情况相比,表现几乎可以肯定是海洋中的下降(提示:在优化之前尝试信封的背面)。

答案 4 :(得分:1)

你应该做你认为最短,最清楚的事情。

然而,为了您的兴趣。

    String hello = "hello " + "world";

最快,因为编译将两个String组合成一个。

对于两个字符串来说这是最快的,因为它避免了创建StringBuilder。

    String helloConcat = "hello ".concat(world);

但是,如果您有两个以上的字符串使用StringBuilder,则隐式或显式最快。

总之,我会使用+,除非你在循环中使用它,在这种情况下我可能会明确地使用StringBuilder来提高性能。

答案 5 :(得分:1)

Concat绝对是两个字符串连接的更快选择,我不知道为什么javac内部使用

(new StringBuilder(String.valueOf(s1))).append(s2).toString()

而不是

s1.concat(s2)

表示s1 + = s2。请参阅我对类似问题concatenation operator (+) vs concat()

的回答

答案 6 :(得分:0)

我找到了这个artical并做了这个测试:

public static void main(String[] args) {
        String s1 = generateString();
        String s2 = generateString();
        String s3 = generateString();
        String s4 = generateString();
        String s5 = generateString();
        String s6 = generateString();

        long e = System.currentTimeMillis();
        for(int i=0;i<10000000;i++){
        //StringBuilder > concat> plus >StringBuffer >plusEqual(">"means faster than)
            //concatPlus(s1 , s2 , s3 , s4 , s5 , s6);//4204ms
            //concatBuilder(s1 , s2 , s3 , s4 , s5 , s6);//2562ms
            //concatBuffer(s1 , s2 , s3 , s4 , s5 , s6);//4610ms
            //concatPlusEqual(s1 , s2 , s3 , s4 , s5 , s6);//9843ms
            //concatConcat(s1 , s2 , s3 , s4 , s5 , s6);//3036ms
        }
        System.out.println(System.currentTimeMillis()-e);           
    }

public static String concatPlusEqual(String s1, String s2, String s3, String s4,
        String s5, String s6) {
       String result = "";
        result += s1;
        result += s2;
        result += s3;
        result += s4;
        result += s5;
        result += s6;
        return result;
}

    public static String concatConcat(String s1, String s2, String s3, String s4,
            String s5, String s6) {
        String result = new String();
        result.concat(s1);
        result.concat(s2);
        result.concat(s3);
        result.concat(s4);
        result.concat(s5);
        result.concat(s6);
        return result;
    }


    public static String concatBuffer(String s1, String s2, String s3, String s4,
            String s5, String s6) {
        return new StringBuffer(s1.length() + s2.length() + s3.length()
                + s4.length() + s5.length() + s6.length()).append(s1)
                .append(s2).append(s3).append(s4).append(s5).append(s6)
                .toString();
    }

    public static String concatBuilder(String s1, String s2, String s3, String s4,
            String s5, String s6) {
        return new StringBuilder(s1.length() + s2.length() + s3.length()
                + s4.length() + s5.length() + s6.length()).append(s1)
                .append(s2).append(s3).append(s4).append(s5).append(s6)
                .toString();
    }

    public static String concatPlus(String s1,String s2,String s3,String s4,String s5,String s6) {
        return s1 + s2 + s3 + s4 + s5 + s6;
    }
public static String generateString()
    {
        Random rng = new Random();
        int length = 10;
        String characters ="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] text = new char[length];
        for (int i = 0; i < length; i++)
        {
            text[i] = characters.charAt(rng.nextInt(characters.length()));
        }
        return new String(text);
    }

StringBuilder 似乎最快, += 最慢​​。 仅供参考!