Сразу же начнем с примера чуть модифицированной программы, которую мы рассматривали тут. В этом варианте мы оставили только тестирование производительности и добавили еще тест на скорость создания строки объекта StringBuilder.
Вывод у этой программы такой:
Я специально вывел в конце длину строки sb, так как иногда результат был и 0мс. То есть конкатенация строк в классе StringBuilder в десятки раз выше.
Теперь разберемся почему же так происходит.
Я уже писал, что в случае использования объектов класса String в цикле конкатенации строки, на каждой итерации создается новый объект класса String, что влечет за собой достаточно большие накладные расходы на выделение памяти для объекта и переопределение ссылок на него.
В случае же объекта класса StringBuilder такого не происходит и как видите скорость работы в десятки раз выше.
Кроме всего прочего, конкатенация строк класса String при помощи перегруженного оператора плюс (+) не явно использует класс StringBuilder, а это означает, что в цикле, каждый раз создается новый объект не только класса String, но еще и класса StringBuilder. Вот от сюда и такие накладные расходы.
Чтобы понять еще глубже, что происходит в данной программе, можно ее декомпилировать программой javap, входящей в состав JDK.
Это можно сделать так: javap -c String012 > String012.txt
В данном случае мы перенаправили вывод работы javap в текстовый файл String012.txt, иначе бы вывод произошел на экран, что не очень удобно для анализа.
Файл получается достаточно многострочный, поэтому тут буду приводить его частями. И так! Первый цикл в студию!
Как видите, хотя в цикле создания строки sl, класс StringBuilder у нас вообще не упоминается, но компилятор решил все равно его использовать, поскольку он работает намного эффективнее. И как я и говорил каждый раз в цикле создаются объекты классов String и StringBulder. Ровно тоже самое происходит и для строки so, поэтом отдельно ее рассматривать не будем. А вот создание строки класса StringBuilder рассмотреть интересно:
Тут, как говорится, совсем другой кордебалет. Что называется почувствуйте разницу :) В данном случае объект каждый раз не создается в цикле. Просто к одной и той же строке (объекту) в цикле добавляется "1".
Это мы рассмотрели самые большие грабли, которые могут быть при конкатенации строк. Но есть еще и поменьше :)
Они даже рассмотрены в оригинальной документации Oracle.
Мы их быстренько рассмотрим на таких же простых примерах и двинемся дальше.
Эта простая программа генерирует следующий вывод:
Собственно на примере все понятно, что в первом случае сперва произошло вычисление операции 2+3, а затем преобразование всего выражения к строке, в соответствии с порядком проведения вычислений. Во втором случае же, сперва произошло приведение всего выражения к строке.
Комментариев нет:
Отправить комментарий