Java 为什么用stringbuilder连接字符串需要更长的时间?

Java 为什么用stringbuilder连接字符串需要更长的时间?,java,stringbuilder,Java,Stringbuilder,我在工作中的一些代码中发现了一个部分,其中使用以下格式创建了一组长字符串: String s = "" + "...\n" + "...\n" + 出于好奇,我决定做一个快速测试,看看StringBuilder是否能带来明显的变化 public class TestStringConcat { public static void main(String[] args) { int arraySize = 1000000; String

我在工作中的一些代码中发现了一个部分,其中使用以下格式创建了一组长字符串:

String s = "" +
    "...\n" +
    "...\n" +
出于好奇,我决定做一个快速测试,看看StringBuilder是否能带来明显的变化

public class TestStringConcat {

    public static void main(String[] args) {
        int arraySize = 1000000;
        String[] strings1 = new String[arraySize];
        String[] strings2 = new String[arraySize];

        System.out.println("Testing concat version");

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < arraySize; i++) {
            strings1[i] = "" +
                "A big long multiline string"; //35 lines of string omitted 
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Time to concat strings: " + (endTime - startTime));

        System.out.println("Now testing with stringbuilder ");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < arraySize; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append("A big long multiline string"); //35 lines of string omitted 
            strings2[i] = sb.toString();
        }
        endTime = System.currentTimeMillis();
        System.out.println("Time to build strings with stringbuilder: " + (endTime - startTime));

    }

}

我以为StringBuilders应该更快,但在这种情况下,速度要慢得多。发生了什么事?

第一部分没有进行任何连接。连接发生在编译时。它所做的只是在数组的所有索引中存储相同、唯一的长字符串

在循环中连接时应使用StringBuilder。即使在运行时使用

"a" + someVar + "b" + someOtherVar;
编译器生成使用StringBuilder连接的代码,或者至少以与StringBuilder相同的速度使用代码,具体取决于Java版本

慢的是:

String s = "";
for (String e : array) {
    s += e;
}

这就创建了很多,临时字符串数组的每个元素一个,这些临时字符串的许多副本被复制到下一个元素中。

字符串编译时是常量吗?它们是在编译时完成的,你只是让事情变慢了。想想看——这是错误的,现在是对的:编译器生成使用StringBuilder的代码——因为JEP280指示字符串Concatenation@BoristheSpider生成的字节码不直接使用StringBuilder,而是使用indy,但是我不知道现在indy调用的StringConcatFactory使用的字符串连接的实际实现实际使用了什么。我猜它仍然使用StringBuilder。无论如何,我会重新措辞。
String s = "";
for (String e : array) {
    s += e;
}