Javolution
От: Аноним  
Дата: 25.02.05 17:46
Оценка:
У кого есть своё мнение о Javolution
Re: Javolution
От: Аноним  
Дата: 02.03.05 14:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>У кого есть своё мнение о Javolution


фигня полная. собственно, создание объекта (new DummyObject()) происходит быстрее чем взятие его из пула. это подтверждает их-же тест.
далее — за счет отсутствия инициализации массива нулями они выигрывают в тестах на создание массивов и как следствие — создание длинных строк.

короче, эта фигня полезна только для микробенчмарков и циклов. в реальности их стэковый пул никому не нужен т.к. обычно работа с сообщением происходит не в циклах (например, servlet container не умеет давать на обработку сразу несколько страниц) а по одному.
Re[2]: Javolution
От: Аноним  
Дата: 02.03.05 14:36
Оценка:
Естесьвенно это не панацея от всех бед.
Данная штука полезна при реализации вычислительных алгоритмов.
Например, парсеры из одного формата в другой.
Их вариант реализации текстовой строки в виже дерева, тоже не плох,
в ряде случаев может существенно ускорить работу алгоритма.

Короче говоря, это штука может быть полезной

NotGonnaGetUs.
Re[2]: Javolution
От: dshe  
Дата: 02.03.05 14:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>...servlet container не умеет давать на обработку сразу несколько страниц) а по одному.

почему это?
--
Дмитро
Re[3]: Javolution
От: Аноним  
Дата: 03.03.05 09:12
Оценка: +1
А>Их вариант реализации текстовой строки в виже дерева, тоже не плох,
А>в ряде случаев может существенно ускорить работу алгоритма.

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

print("StringBuilder \"append\" : ");
startTime();
for (int i=0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < COUNT; j++) {
sb.append(PLUS_STRING);
}
!!!! String x = sb.toString();
}
endTime(100);

print("Text \"concat\" (stack): ");
startTime();
for (int i=0; i < 100; i++) {
PoolContext.enter();
Text txt = Text.EMPTY;
for (int j = 0; j < COUNT; j++) {
txt = txt.concat(PLUS_TEXT);
}
!!!! String x = txt.toString();
PoolContext.exit();
}
endTime(100);

то Text сольет вчистую, а без получения строки канкатенация бессмыслена (нельзя распечатать Text напрямую, нельзя его записать в файл или отправить в поток...). не говоря уже о том, что у StringBuilder есть замечательный метод setLength(0) с применением которого Text сливает в 3-5 раз.

конечно, insert & delete — да, тут Text рвет всех, как-же копировать не надо... только вот GC начнет сильно тормозить из-за огромного кол-ва созданных мелких объектов, а борьба с ним вродебы и была главной целью этого Javolution. да и insert/delete достаточно редкие операции. кроме того, память будет кушать нехило т.к. при delete неиспользованная информация будет оставаться в памяти (причем надолго — пул ведь).

A> Данная штука полезна при реализации вычислительных алгоритмов.

A> Например, парсеры из одного формата в другой.

насчет парсеров — очень сильно сомневаюсь, если использовать простейшие оптимизации то Javolution сольет по перформансу... единственная возможная польза — это меньшие GC паузы. но, с современными коллекторами весьма сомнительный плюс с учетом того что создание объекта происходит быстрее чем его взятие из пула, кроме того, GC все равно будет происходить и непонятно что хуже — уничтожение объектов или намного более сложное дерево ссылок.
Re[4]: Javolution
От: NotGonnaGetUs  
Дата: 06.03.05 13:27
Оценка:
Я не много о другом говрил.

В оптимизации простого метода типа
String foo(xxx) {
...
return (String)yyy;
}
использование Text не сильно поможет.

А вот переделка его в
Text foo(xxx) {
...
return (Text)yyy;
}
может дать не плохой эффект.

Например, парсер, который из String в хитром формате строит мат.выражение, которое затем может быть вычислено, сравнено и т.д.
Парсер на вход получает строку, на выходе отдаёт экземпляр выражения. Внутри можно смело все String заменить на Text.
Думаю в этом случае можно ожидать прирост производительности.


На счёт того, что доступ к кешу занимает больше времени, чем простое создание объекта...
В случае создания единичных екземпляров класса — кеширование излижне.
Если же у нас работает цикл, в котором постоянно создаётся куча объектов,
при том, что сохраняются ссылки только на небольшое кол-во созданных объектов — выгода может быть.

Вот пример "из жизни".
Map c ключём состоящим из String + int.
В алгоритми часто требовалось проверить(действительно часто, существует ли такой-то элемент.
Для этого я сначала создавал new Key(String, int) и проверял map.contians(key).
Потом, прикинул, и добавил в Key метод reset и в класс использующий кey добавил переменную класса Кey,
которую при необходимости использовал (key.reset(String,int)).
В итоге с 300мс время работы алгоритма снизилось до 100мс.
Если бы key хранился в кеше, а не как поле класса, думаю, результат не сильно отличался бы.


Короче говоря, я не согласен с вашей пессимистической оценкой javalution
и при первой возможно попробую этой штукой воспользоваться
Re[5]: Javolution
От: Аноним  
Дата: 25.03.05 11:42
Оценка:
Здравствуйте, NotGonnaGetUs, Вы писали:

NGG>Например, парсер, который из String в хитром формате строит мат.выражение, которое затем может быть вычислено, сравнено и т.д.

NGG>Парсер на вход получает строку, на выходе отдаёт экземпляр выражения. Внутри можно смело все String заменить на Text.
NGG>Думаю в этом случае можно ожидать прирост производительности.

очень очень редкий случай. как правило, результируящая строка куда-то записывается, а для этого нужно из нее сделать String...
кроме того, если все "смело заменить на Text" то мноогие операции замедлятся — например, substring и charAt. как раз charAt и является типичной операцией парсера, а в ней Text сольет очень сильно.

NGG>Потом, прикинул, и добавил в Key метод reset и в класс использующий кey добавил переменную класса Кey,

NGG>которую при необходимости использовал (key.reset(String,int)).
NGG>В итоге с 300мс время работы алгоритма снизилось до 100мс.
NGG>Если бы key хранился в кеше, а не как поле класса, думаю, результат не сильно отличался бы.

дело в том, что в случае кэша нужна синхронизация и/или поиск. если вы вашу функцию reset() объявите как synchronized, то она будет занимать почти в 10 раз больше времени чем честный конструктор. кстати, в JDK 5.0 простые конструкторы стали раза в 3 быстрее по сравнению с JDK 1.4.x, и вообще выделение памяти работает в Java намного быстрее чем malloc() т.к. память не фрагментирована.

в javolution есть два типа пулов — HeapPool, он с синхронизацией, заведомо медленнее чем конструктор и LocalPool, без синхронизации, но, делает поиск в связанном списке. даже микробенчмарк javolutionа честно признается что он сливает (на JDK 5.0, JDK 1.4.x все-таки чуть медленнее)

-- Heap versus Stack Allocation (Pool-Context) --
Object heap creation: 36ns
Object stack creation: 46ns

правда при создании массивов выигрывает, но, при этом "забывает" инициализировать массив нулями каждый раз, семантика сильно отличается, многие алгоритмы заточены на то что массив инициализирован.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.