#java #stringbuilder
#java #stringbuilder
Вопрос:
Я нашел раздел в каком-то коде на работе, где куча длинных строк была создана с использованием этого формата:
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. Является ли время компиляции строк постоянным? Они выполняются во время компиляции, и вы только что замедлили работу.
Ответ №1:
Первая часть не выполняет никакой конкатенации. Объединение происходит во время компиляции. Все, что он делает, это сохраняет одну и ту же уникальную длинную строку во всех индексах массива.
При объединении в цикле следует использовать StringBuilder. Даже когда вы объединяете динамические данные во время выполнения с помощью
"a" someVar "b" someOtherVar;
Компилятор генерирует код, который использует StringBuilder для объединения (или использует код по крайней мере так же быстро, как это делал бы StringBuilder, в зависимости от версии Java).
Что является медленным, так это:
String s = "";
for (String e : array) {
s = e;
}
Это создает много (ну, по одной на элемент массива) временных строк и множество копий этих временных строк в следующую строку.
Комментарии:
1. Просто думаю — в наши дни это неправильно, верно: » Компилятор генерирует код, который использует StringBuilder » — начиная с JEP280 «Индифицировать конкатенацию строк»
2. @BoristheSpider сгенерированный байтовый код не использует StringBuilder напрямую, а вместо этого использует indy, но я не знаю, что на самом деле используется в настоящее время фактической реализацией конкатенации строк, используемой StringConcatFactory, вызываемой indy. Я предполагаю, что он все еще использует StringBuilder. Я все равно перефразирую.