Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Как "зачистить" StringBulider?


Автор: BlHol 15.8.2007, 09:13
День добрый!

Объявляю 
Код

StringBuilder sb = new StringBuilder(" ") ;


Затем он у меня заполняется, потом идет цикл, в котором в начале каждого прохода он должен зачищаться.

Вопрос: как это сделать без объявления нового StringBuilder'а?
Скорее всего, плохо искал, но метода не нашел...

Заранее спасибо.
С уважением.

Автор: AlexeyVorotnikov 15.8.2007, 10:05
Код

sb.delete(0, sb.length()-1);


Добавлено через 9 минут и 3 секунды
Вот так лучше:
Код

sb.setLength(0);

Автор: BlHol 15.8.2007, 10:56
Огромное спасибо!

Автор: polosatij 15.8.2007, 13:37


а зачем ты используешь вообще этот класс? насколько я знаю, ява 6 или, НАВЕРНО, даже 5 (надо посмотреть в байткод) оптимирует данные проблемы со стрингом  smile 

Автор: AlexeyVorotnikov 15.8.2007, 13:49
Цитата(polosatij @  15.8.2007,  14:37 Найти цитируемый пост)
данные проблемы со стрингом

Какие проблемы?

Автор: Shaggie 15.8.2007, 13:50
Цитата(polosatij @  15.8.2007,  14:37 Найти цитируемый пост)
а зачем ты используешь вообще этот класс? насколько я знаю, ява 6 или, НАВЕРНО, даже 5 (надо посмотреть в байткод) оптимирует данные проблемы со стрингом

Во-первых, не всегда есть возможность использовать 6 или даже 5. Это, конечно, никак не прогрессивно, но таковы реалии жизни.
Во-вторых, вот как раз вчера работал с регэкспом, точнее, с функцией appendReplacement(StringBuffer, String). Читать первым параметром String она не соглашалась ни в какую!

А пор теме. Почему бы не использовать переобъявление?
Код

sb = new StringBuilder("");

Это гораздо быстрее вызовов методов и код стопроцентно читабелен.

Добавлено через 1 минуту и 26 секунд
Правда, сиплюсплюсники меня на месте бы загрызли... но в условиях GC - чем не выход?

Добавлено через 2 минуты и 10 секунд
Сорри, стрингбилдер со стрингбуффером перепутал. Это с недосыпу, не иначе!

Автор: w1nd 15.8.2007, 13:57
Цитата(polosatij @  15.8.2007,  13:37 Найти цитируемый пост)
а зачем ты используешь вообще этот класс? насколько я знаю, ява 6 или, НАВЕРНО, даже 5 (надо посмотреть в байткод) оптимирует данные проблемы со стрингом

Никто ничего не оптимизирует.
А использование сложения строк в циклах  - это вообще ужас в плане производительности и расхода памяти.

Цитата(Shaggie @  15.8.2007,  13:50 Найти цитируемый пост)
Это гораздо быстрее вызовов методов и код стопроцентно читабелен.

Кто вам сказал такую глупость? Во-первых, это стопроцентно медленнее вызова метода (особенно setLength). Во-вторых, нельзя заранее сказать насколько медленнее - в худшем случае вы запустите сборщик мусора. 

Автор: Shaggie 15.8.2007, 14:07
Каюсь... пошёл отсыпаться.

Автор: polosatij 15.8.2007, 14:13
Цитата(w1nd @  15.8.2007,  13:57 Найти цитируемый пост)
Никто ничего не оптимизирует.



да? тогда посмотри в байт код следующей строки:

Код

String foo = "hi";
String bar = "hi2"; // динамическое присвоение переменной!

....

String foobar = foo + bar;


 smile 

Автор: polosatij 15.8.2007, 20:26
Цитата(w1nd @  15.8.2007,  13:57 Найти цитируемый пост)
А использование сложения строк в циклах  - это вообще ужас в плане производительности и расхода памяти.


у тебя пробел в образовании..  smile  это было так раньше smile , сейчас уже всё по другому.. посмотри байткод явы 6 (и думаю такое же будет в ява 5) smile

Автор: niasilil 16.8.2007, 07:23
Цитата(polosatij @ 15.8.2007,  20:26)
Цитата(w1nd @  15.8.2007,  13:57 Найти цитируемый пост)
А использование сложения строк в циклах  - это вообще ужас в плане производительности и расхода памяти.
у тебя пробел в образовании..  smile  это было так раньше smile , сейчас уже всё по другому.. посмотри байткод явы 6 (и думаю такое же будет в ява 5) smile

погоди, погоди, как так? Чего, String pool по другому стал работать что ли? Я почему то всегда считал что если один раз создал String объект, его уже не убьешь. 
Можно подробности или ссылочку?

Автор: mindflyer 16.8.2007, 09:05
Цитата(polosatij @  15.8.2007,  20:26 Найти цитируемый пост)
это было так раньше smile , сейчас уже всё по другому.. посмотри байткод явы 6 (и думаю такое же будет в ява 5)


В 6-ой не знаю, но 5-ая точно без оптимизаций. Недавно под профайлером смотрел работу нашей системы, пришёл в тихий ужас над участком программы, в котором строилась строка из 10 подстрок. Просто дикие потери памяти и быстродействия, которые вылечились использованием StringBuilder.

Автор: polosatij 16.8.2007, 13:28


Цитата(niasilil @  16.8.2007,  07:23 Найти цитируемый пост)
Можно подробности или ссылочку? 


просто посмотри байткод  smile 

Цитата(niasilil @  16.8.2007,  07:23 Найти цитируемый пост)
Я почему то всегда считал что если один раз создал String объект, его уже не убьешь. 


не в этом дело.. там компилярор по ходу все String1 + String2 заменяет на StringBuffer sb = new StringBuffer(); и потом append.. ыыы  smile 

Цитата(mindflyer @  16.8.2007,  09:05 Найти цитируемый пост)
Просто дикие потери памяти и быстродействия, которые вылечились использованием StringBuilder. 


ага.. я тоже так делал, но когда в последний раз посмотрел бакткод, то был удивлён и больше этого не делаю, т.к. работаю на ява 6  smile 

Автор: nornad 16.8.2007, 16:03
Цитата(polosatij @  16.8.2007,  16:28 Найти цитируемый пост)
ага.. я тоже так делал, но когда в последний раз посмотрел бакткод, то был удивлён и больше этого не делаю, т.к. работаю на ява 

Напрасно. Никто ведь не гарантирует, что в java 7 эта оптимизация останется. Лучше пока что делать явно со стрингбилдером. А вот когда они его официально прибьют за ненадобностью - тогда и складывать строки. smile 

Автор: niasilil 16.8.2007, 21:25
Цитата(polosatij @ 16.8.2007,  13:28)
там компилярор по ходу все String1 + String2 заменяет на StringBuffer sb = new StringBuffer(); и потом append.. ыыы  smile 

Очень интересно, спасибо. Дал бы плюса, да рейтинг маловат пока. Если только модераторы поставят за меня. 

Автор: mindflyer 16.8.2007, 22:24
Цитата(polosatij @  16.8.2007,  13:28 Найти цитируемый пост)
ага.. я тоже так делал, но когда в последний раз посмотрел бакткод, то был удивлён и больше этого не делаю, т.к. работаю на ява 6  smile  

Хм, но ведь компилятор не всё сможет оптимизировать, например, когда построение итоговой строки зависит от результатов работы функций. Типа:
Код

String result = "start";
if ( getBlaBlaBla() == 4 ) {
   result += "1";
   send(result);
} else {
   result += "2";
   write(result);
}


Или он и такие вещи умеет оптимизировать? Как-то не доверяю я возможностям оптимизации в сложных конструкциях smile Лучше уж в таких ситуациях по старинке, со StringBuilder'ом.

Автор: sergejzr 16.8.2007, 23:02
А что там сложного оптимизировать?
Код

StringBuffer result = new StringBuffer(); 
result.append("start");
if ( getBlaBlaBla() == 4 ) {
   result.append("1");
   send(result.toString());
} else {
    result.append("2");
   write(result.toString());
}

Цитата(nornad @  16.8.2007,  15:03 Найти цитируемый пост)
Напрасно. Никто ведь не гарантирует, что в java 7 эта оптимизация останется.

Она скорее даже ещё улучшится.

В любом случае "грязную рутинную работу" надо оставлять роботам - т.е компилятору. Лучше оптимизатора человек всё равно не соптимирует. 
А вот читабельность должна на первом месте стоять. 

Но конечно setLength(0); - самы быстрый вариант. И такое точно оптимизатор не возьмёт.

Автор: COVD 16.8.2007, 23:14
Где-то в учебнике видел фразу, что StringBuilder - это несинхронизированная версия StringBuffer' а . Примерно также соотносятся, как Vector и ArrayList. Просто и понятно. А прочитав эту дискуссию, так ничего и не понял. Как же лучше складывать строки в java 6? (в байт код не отсылайте smile )

Автор: sergejzr 16.8.2007, 23:20
COVD, плюсом.

Автор: w1nd 16.8.2007, 23:30
Цитата(sergejzr @  16.8.2007,  23:20 Найти цитируемый пост)
COVD, плюсом.

Только не в циклах.

Цитата(polosatij @ 15.8.2007,  20:26)
у тебя пробел в образовании..  smile  это было так раньше smile , сейчас уже всё по другому.. посмотри байткод явы 6 (и думаю такое же будет в ява 5) smile

Я бы с радостью восполнил пробел в образовании, если бы он был smile

Упомянутая вами "оптимизация" имела место ещё в версии 1.4.0 (возможно и в более ранних, я не интересовался). И заключается она _только_ в подмене операций со строками на операции со StringBuffer'ом (до 1.5) или StringBuilder'ом. Это я за оптимизацию не считаю вовсе.

Конкатенация строк вида 
Код
String s2 = s1 + "2";

преобразуется компилятором в код, создающий два-три (зависит от ситуации) _лишних_ объекта. При этом расходуется _как минимум_ в полтора раза больше памяти, чем при использовании StringBuilder'а. Именно эта "оптимизация", помещённая в цикл, и приводит к огромным потерям времени и значительным потерям памяти _впустую_.

З. Ы. Особенно времени. Дополнение StringBuilder'а (каждый может написать для себя простенький тест, дабы убедиться воочию) быстрее конкатенации строк (якобы оптимизируемой) в _тысячи раз_.

Автор: COVD 16.8.2007, 23:36
Цитата

Только не в циклах.


Тогда везде бы надо StringBuilder использовать. Надо ли понимать так, что str1+str2 - это наглядно и потому хорошо, но в цикле это большая роскошь. 

Автор: w1nd 16.8.2007, 23:40
Цитата(COVD @  16.8.2007,  23:36 Найти цитируемый пост)
Надо ли понимать так, что str1+str2 - это наглядно и потому хорошо, но в цикле это большая роскошь. 

 smile 

Автор: mindflyer 16.8.2007, 23:59
Цитата(sergejzr @  16.8.2007,  23:02 Найти цитируемый пост)
В любом случае "грязную рутинную работу" надо оставлять роботам - т.е компилятору. Лучше оптимизатора человек всё равно не соптимирует. 
А вот читабельность должна на первом месте стоять. 

Согласен (иногда бывает наоборот, но речь не об этом). Современный java-компилятор (6-ой, 5-ый...) действительно умеет делать такие оптимизации, как ты привёл в коде?

Автор: w1nd 17.8.2007, 11:49
Цитата(mindflyer @  16.8.2007,  23:59 Найти цитируемый пост)
Согласен (иногда бывает наоборот, но речь не об этом). Современный java-компилятор (6-ой, 5-ый...) действительно умеет делать такие оптимизации, как ты привёл в коде?

Такие не умеет. И, смею предположить, не сумеет никогда. Просто на месте каждого сложения будет создан StringBuilder, вызван append, и результат обратно в переменную с помощью toString().

Автор: Shaggie 17.8.2007, 12:22
На свежую голову провёл эксперимент.
Код

String a = "hi";
String b = "all";
String c = a+b; // компилируется в String c = new StringBuilder().append(a).append(b).toString();

В то время как
Код

String a = "hi";
String b = "all";
String c = new StringBuilder(a).append(b).toString();

экономит три байта и лишний вызов метода append()

Вот такая мелочная оптимизация.

Особенно забавно, что мы не знаем, как реализованы вызовы конструкторов StringBuilder - какой из них эффективнее  smile 

Автор: nornad 17.8.2007, 13:10
Цитата(sergejzr @  17.8.2007,  02:02 Найти цитируемый пост)
Лучше оптимизатора человек всё равно не соптимирует.

Да ну? Совершенно не согласен. smile

Автор: sergejzr 17.8.2007, 13:25
Цитата(nornad @  17.8.2007,  12:10 Найти цитируемый пост)
Да ну? Совершенно не согласен. smile 

Вместо "лучше" следовало бы написать "эффективнее". Это true.

Автор: nornad 17.8.2007, 16:28
sergejzr, всё равно не согласен. Человек способен оптимизировать куда лучше и эффективнее, чем любой компилятор, оптимизатор и иже с ними. А вот то, что человек затратит на это куда больше времени - это уже как раз true.
То есть, оптимизация выходит у человека эффективнее, но сам процесс оптимизирования у него неэффективен. smile

Автор: sergejzr 18.8.2007, 02:04
Цитата(nornad @  17.8.2007,  15:28 Найти цитируемый пост)
sergejzr, всё равно не согласен. Человек способен оптимизировать куда лучше и эффективнее, чем любой компилятор, оптимизатор и иже с ними.

 А что есть по Вашему эффективность?  Уж время это один из главных влияющих факторов. И кто этот абстрактный "человек"? Если среднего программиста взять, то точно оптимизатор лучше, а если крутого, то его сперва надо взять где-то, да и он наврядли будет оптимизировать ваш код. А зачем нам учитывать теоретическую эффективность, которая не может быть достигнута на практике?
ПС:
Не стоит придираться к словам. И так понятно, что имеется ввиду, а то - уходим от темы.




Цитата(w1nd @  17.8.2007,  10:49 Найти цитируемый пост)
Такие не умеет. И, смею предположить, не сумеет никогда.

Да, действительно (проверил дисассемблером). Ява оптимизатор оказывается и правда ещё в младенческом возрасте находится. 

Насчёт не сумеет никогда - я бы сомневался. Конструкция не очень тяжёлая. Её возможно даже препроцессором (заменой выражений "побуквенно") можно взять (если бы он у явы был smile) )

Автор: nornad 18.8.2007, 06:12
Под эффективностью я понимал то, что человек может оптимизировать код так, что он (код) после этой процедуры будет эффективнее. Эффективность кода и эффективность процесса оптимизации кода - разные вещи. Думаю, теперь мы разобрались с тем, кто и что имел в виду.

А по поводу уровня "человека" могу сказать то, что объективно нет такого понятия как "средний программист". Так же, как нет и других категорий. Потому что вообще ничего объективного у нас нет. Но это я уже ударился в совсем иные сферы бытия.
Кто же может оптимизировать лучше, чем некий обобщённый оптимизатор? Знамо дело - умный и усидчивый, имеющий достаточно знаний и стимул для этого.
Если вы, уважаемый, работали с ассемблером, то посмотрев на скомпилированный код любого приложения вы сможете заметить хотя бы пару мест, где можно было бы оптимизировать.
Ну и думаю, без объяснений понятно, что человек сначала даст возможность показать себя оптимизатору, а потом уже при необходимости сам полезет оптимизировать. Так и время экономится, и оптимизация увеличивается, если это необходимо.

Автор: lando1 18.8.2007, 21:58
[QUOTE=nornad,16.8.2007,  16:03]
Цитата(polosatij @  16.8.2007,  16:28 Найти цитируемый пост)
...Никто ведь не гарантирует, что в java 7 эта оптимизация останется. Лучше пока что делать явно со стрингбилдером. А вот когда они его официально прибьют за ненадобностью - тогда и складывать строки. smile


Почему-это StringBuilder прибьют? Если использовать однопоточные приложения - то он предпочтительней StringBuffer по скорости - ибо несинхронизирован.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)