7 июн. 2015 г.

Строки. Часть 4 – конкатенация строк.

Str001

Сразу же начнем с примера чуть модифицированной программы, которую мы рассматривали тут. В этом варианте мы оставили только тестирование производительности и добавили еще тест на скорость создания строки объекта StringBuilder.

Вывод у этой программы такой:

Str002Я специально вывел в конце длину строки sb, так как иногда результат был и 0мс. То есть конкатенация строк в классе StringBuilder в десятки раз выше.

Теперь разберемся почему же так происходит.

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

В случае же объекта класса StringBuilder такого не происходит и как видите скорость работы в десятки раз выше.

Кроме всего прочего, конкатенация строк класса String при помощи перегруженного оператора плюс (+) не явно использует класс StringBuilder, а это означает, что в цикле, каждый раз создается новый объект не только класса String, но еще и класса StringBuilder. Вот от сюда и такие накладные расходы.

Чтобы понять еще глубже, что происходит в данной программе, можно ее декомпилировать программой javap, входящей в состав JDK.

Это можно сделать так: javap -c String012 > String012.txt

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

Файл получается достаточно многострочный, поэтому тут буду приводить его частями. И так! Первый цикл в студию!

Str003 

Как видите, хотя в цикле создания строки sl, класс StringBuilder у нас вообще не упоминается, но компилятор решил все равно его использовать, поскольку он работает намного эффективнее. И как я и говорил каждый раз в цикле создаются объекты классов String и StringBulder. Ровно тоже самое происходит и для строки so, поэтом отдельно ее рассматривать не будем. А вот создание строки класса StringBuilder рассмотреть интересно:

Str004

Тут, как говорится, совсем другой кордебалет. Что называется почувствуйте разницу :) В данном случае объект каждый раз не создается в цикле. Просто к одной и той же строке (объекту) в цикле добавляется "1".

Grabli

Это мы рассмотрели самые большие грабли, которые могут быть при конкатенации строк. Но есть еще и поменьше :)

Они даже рассмотрены в оригинальной документации Oracle.

Мы их быстренько рассмотрим на таких же простых примерах и двинемся дальше.

 

Str00031

Эта простая программа генерирует следующий вывод:

Str00032

Собственно на примере все понятно, что в первом случае сперва произошло вычисление операции 2+3, а затем преобразование всего выражения к строке, в соответствии с порядком проведения вычислений. Во втором случае же, сперва произошло приведение всего выражения к строке.

Комментариев нет:

Отправить комментарий