Почему объединение строк с помощью stringbuilder занимает больше времени? - PullRequest
0 голосов
/ 15 марта 2019

В каком-то коде на работе я нашел раздел, в котором была создана куча длинных строк с таким форматом:

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

    }

}

Вывод:

Testing concat version
Time to concat strings: 5
Now testing with stringbuilder 
Time to build strings with stringbuilder: 2455

Я думал, что StringBuilders где-то должен быть быстрее, но в этом случае это намного медленнее.Что происходит?

1 Ответ

7 голосов
/ 15 марта 2019

Первая часть не делает никакой конкатенации.Конкатенация происходит во время компиляции.Все, что он делает - это сохраняет одну и ту же уникальную длинную строку во всех индексах массива.

При объединении в цикле следует использовать StringBuilder.Даже когда вы объединяете динамические вещи во время выполнения, используя

"a" + someVar + "b" + someOtherVar;

Компилятор генерирует код, который использует StringBuilder для конкатенации (или использует код по крайней мере так же быстро, как это делает StringBuilder, в зависимости от версии Java).

Что медленно:

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

Это создает много (ну, по одному на элемент массива) временных строк и множество копий этих временных строк вследующий.

...