+= 比 concat 更高效吗?

发布于 2024-10-05 00:07:08 字数 495 浏览 2 评论 0原文

我一直在阅读我团队中其他开发人员编写的代码,他们似乎更喜欢使用 += 进行字符串连接,而我更喜欢使用 .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);
    }
}

I've been reading code produced by other developers on my team, they seem to favor using += for String concatenation, whereas I prefer using .concat() as it feels easier to read.

I'm trying to prepare an argument as to why using .concat() is better, and I'm wondering, is there any difference in efficiency between the two?

Which option "should" we be taking?

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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

铃予 2024-10-12 00:07:09

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

就性能而言,concat 优于 +。只要您只使用一个或两个即可。

对于concat,您最终将创建一个具有正确大小的char[]String对象。这是你能得到的尽可能最佳的结果。

对于 + javac 生成的代码构造 StringBuilder 来执行附加操作,然后转换为 String。从 1.5 开始,您创建:

  • StringBuilder (浪费)
  • StringBuilder 的初始 char[] (浪费)
  • 如果生成的序列太长,则使用第二个更大的序列char[](浪费)
  • 生成的String
  • Stringchar[]

但是,您很少看到使用 concat,因为它更难以阅读。与其他正在发生的事情相比,几乎可以肯定,性能只是沧海一粟(提示:在优化之前先尝试一下信封背面)。

In terms of readability, I think you are very wrong. + wins over .concat(). If you are using +=, you might want to think about StringBuilder.append keeping the same StringBuilder for the loop.

In terms of performance concat is better than +. so long as you only use one or perhaps two.

In the case of concat, you will end up creating a String object with a correctly sized char[]. It's about as optimal as you can get.

For + javac generates code that constructs a StringBuilder to do the appending and then converts to a String. From 1.5 you create:

  • A StringBuilder (waste)
  • Initial char[] for StringBuilder (waste)
  • If resulting sequence is too long, a second bigger char[] (waste)
  • The resulting String.
  • The String's char[].

However, you rarely see concat used because it is more difficult to read. The performance is almost certainly going to be a drop in the ocean compared to what else is going on (hint: try the back of an envelope before optimising).

铃予 2024-10-12 00:07:09

你应该做你认为最短、最清晰的事情。

不过,为了你的兴趣。

    String hello = "hello " + "world";

是最快的,因为编译将两个字符串合并为一个。

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

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

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

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

You should do what you find is the shortest and clearest to you.

However, for your interest.

    String hello = "hello " + "world";

Is the fastest as the compile combined the two String into one.

This is fastest for two Strings as it avoids creating StringBuilder.

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

However if you have more than two strings Using StringBuilder, either implicitly or explicitly is fastest.

In summary I would use + unless you have it in a loop in which case I might use StringBuilder explicitly to improve performance.

驱逐舰岛风号 2024-10-12 00:07:09

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

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

而不是

s1.concat(s2)

for s1 += s2。请参阅我对类似问题的回答连接运算符 (+) 与 concat()

Concat is definitely a faster choice for two strings concatination, I don't know why javac internally uses

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

instead of

s1.concat(s2)

for s1 += s2. See my answer to a similar question concatenation operator (+) vs concat()

青衫负雪 2024-10-12 00:07:09

我找到了这个 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 最快,+= 最慢。
仅供参考!

I have found this artical and made this test :

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);
    }

It looks like that StringBuilder is fastest and += is slowest.
Just for reference!

风苍溪 2024-10-12 00:07:08

由于 String 在 java 中是不可变的,因此当您执行 ++=concat(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 与 StringBuffer 与 String.concat 的性能 - 做得正确

Since String is immutable in java, when you do a +, += or concat(String), a new String is generated. The bigger the String gets the longer it takes - there is more to copy and more garbage is produced.

Today's java compilers optimizes your string concatenation to make it optimal, e.g.

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

Compiler generates it to:

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

My advice is to write code that's easier to maintain and read.

This link shows performance of StringBuilder vs StringBuffer vs String.concat - done right

ゝ偶尔ゞ 2024-10-12 00:07:08

应该没关系。现代 Java 编译器、JVM 和 JIT 将以差异最小化的方式优化您的代码。您应该努力编写对您来说更具可读性和可维护性的代码。

It shouldn't matter. Modern day Java compilers, JVMs and JITs will optimize your code in such a way that differences are likely to be minimal. You should strive to write code that's more readable and maintainable for you.

演出会有结束 2024-10-12 00:07:08

我同意@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

I agree with @darioo and most other answers. Always put readability (and maintainability) first. (A modern JIT compiler should have no troubles with simple cases like these.)

Here is however the bytecode corresponding to your program. (Note that the += approach results in a StringBuilder which is generally the preferred approach when constructing strings.)

// 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文