Здравствуйте, 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 все-таки чуть медленнее)
правда при создании массивов выигрывает, но, при этом "забывает" инициализировать массив нулями каждый раз, семантика сильно отличается, многие алгоритмы заточены на то что массив инициализирован.