Подтвердить что ты не робот

Java: String concat vs StringBuilder - оптимизирован, и что мне делать?

В этом ответе, он говорит (подразумевает), что конкатенация String оптимизирована в операциях StringBuilder в любом случае, поэтому, когда я пишу свой код, есть ли основания писать StringBuilder код в источнике? Обратите внимание, что мой вариант использования отличается от вопроса OP, поскольку я конкатенирую/добавляю сотни тысяч строк.

Чтобы я стал яснее: я хорошо осведомлен о различиях каждого из них, я просто не знаю, стоит ли на самом деле писать код StringBuilder, потому что он менее читабельный, и когда его якобы более медленный кузен, класс String, преобразованный автоматически в процессе компиляции.

4b9b3361

Ответ 1

Я думаю, что использование StringBuilder vs + действительно зависит от контекста, в котором вы его используете.

Как правило, с использованием JDK 1.6 и выше компилятор будет автоматически присоединяться к строкам вместе с помощью StringBuilder.

String one = "abc";
String two = "xyz";
String three = one + two;

Это скомпилирует String three как:

String three = new StringBuilder().append(one).append(two).toString();

Это очень полезно и экономит время от времени. Однако этот процесс не всегда оптимален. Возьмем, к примеру:

String out = "";
for( int i = 0; i < 10000 ; i++ ) {
    out = out + i;
}
return out;

Если мы скомпилируем байт-код и затем декомпилируем генерируемый байт-код, получим что-то вроде:

String out = "";
for( int i = 0; i < 10000; i++ ) {
    out = new StringBuilder().append(out).append(i).toString();
}
return out;

Компилятор оптимизировал внутренний цикл, но, конечно же, не сделал оптимальных оптимизаций. Чтобы улучшить наш код, мы могли бы использовать:

StringBuilder out = new StringBuilder();
for( int i = 0 ; i < 10000; i++ ) {
    out.append(i);
}
return out.toString();

Теперь это более оптимально, чем код, сгенерированный компилятором, поэтому определенно необходимо написать код, используя классы StringBuilder/StringBuffer в случаях, когда необходим эффективный код. Текущие компиляторы не очень эффективны при конкатенации строк в цикле, однако это может измениться в будущем.

Вам нужно внимательно посмотреть, где вам нужно вручную применить StringBuilder и попытаться использовать его там, где это также не уменьшит читаемость вашего кода.

Примечание. Я скомпилировал код с помощью JDK 1.6 и декомпилировал код с помощью программы javap, которая выплевывает байт-код. Его довольно легко интерпретировать и часто полезно использовать при попытке оптимизировать код. Компилятор действительно меняет код за кулисами, поэтому всегда интересно посмотреть, что он делает!

Ответ 2

Ключевая фраза в вашем вопросе "предположительно медленнее". Вам нужно определить, действительно ли это узкое место, а затем увидеть, что быстрее.

Если вы собираетесь написать этот код, но еще не написали его, напишите все, что вам лучше, а затем, если это необходимо, посмотрите, является ли это узким местом.

В то время как имеет смысл использовать код, который вы считаете более похожим, чтобы быть быстрее, если оба они одинаково читаемы, на самом деле требуется время, чтобы узнать, что быстрее, когда у вас нет необходимости, это пустая трата времени. Читаемость выше производительности до тех пор, пока производительность неприемлема.

Ответ 3

Это зависит от случая, но StringBuilder считается немного быстрее. Если вы выполняете конкатенацию внутри цикла, я бы предложил вам использовать StringBuilder.

В любом случае, я бы посоветовал вам профилировать и тестировать ваш код (если вы делаете такое массивное приложение).

Будьте осторожны: экземпляры StringBuilder являются изменяемыми и не подлежат обмену между потоками (если вы действительно не знаете, что делаете.), в отличие от String, которые являются неизменяемыми.

Ответ 4

Возможно, я неправильно понял ваш вопрос, но StringBuilder быстрее при добавлении строк. Итак, если вы добавляете "сотни тысяч строк", вам определенно следует использовать StringBuilder (или StringBuffer, если вы используете многопотоковое приложение).

(Более подробный ответ в комментариях)