Про кеширование
Если у вас
condition
бОльшую часть времени имеет малый набор возможных значений, то кешированием в данном случае будет создание хешмапы, где ключ -
condition
, значение -
condition + ","
. Можете даже использовать какой-нибудь LRU-кеш, что бы редко используемые ключи постепенно удалялись из кеша и не занимали память.
Но если честно, в данном случае операция
condition + ","
настолько незначительна по вычислительной сложности, что хоть какое-то изменение вы заметите только если у вас этот участок кода вызывается в горячем цикле и генерирует столько мусора, что паузы GC перевешивают дополнительные вычисления хеша, ветвления и добавление новых данных в кеш. Но даже в этом случае нужно профилировать, например с помощью
JMH и VisualVM.
Теперь по поводу StringBuilder.
Сразу скажу, что у меня нет под рукой IDE для Java, что бы проверить то, что будет написано дальше, все выводы сделаны только глядя на исходный код классов
String и
StringBuilder. Итак, поехали:
Итого, у вас создаётся минимум 6 объектов.
Если переменная
condition
может иметь произвольное значение (т.е. операции с ней нет смысла кешировать, так как всё-равно придётся каждый раз вычислять новое значение), то можете попробовать воспользоваться методом
condition.concat(String str)
- будете создавать только 1 объект вместо 2. Будет ли это быстрее? Не знаю, надо профилировать.
Далее, после входа в блок
if
создаём новый StringBuilder вместимостью
a.length() + condition.length() + 2
. Если не указать длину строки, то вместимость у
StringBuilder
будет либо 16 символов, либо равной длине значения в переменной
a
(в зависимости от того, какой конструктор будет использован). И при конкатенации с новыми строками скорее всего возникнет необходимость увеличивать размер буфера, что приведёт к дополнительному копированию массивов (создать буфер с новым размером, скопировать содержимое старого буфера в новый). Поэтому желательно сразу рассчитать правильную длину результирующей строки. В любом случае, это тоже +1 объект.
a.replace(CharSequence target, CharSequence replacement)
можно заменить методом
StringBuilder.replace(int start, int end, String str)
(придётся вручную вычислить начало и конец подстроки, которую вы хотите заменить).
Вместо
a = a + System.lineSeparator();
используйте
a.append(System.lineSeparator())
.
out.append(a);
приведёт к созданию еще 1 объекта - либо вы вручную вызовете
a.toString()
, либо этот метод будет вызван за вас в методе
out.append(CharSequence seq)
. И скорее всего приведёт еще и к копированию массива символов внутри переменной
out
, если вы заранее не указали вместимость с запасом.
Итого, 3 объекта против изначальных 6 с несколькими не сразу очевидными НО. Стоит ли усложнение кода полученной экономии? Не уверен, надо профилировать. Ну и учтите, что производительность самого
StringBuilder
может быть разной,
в зависимости от того, как вы его используете.
Имхо, то что вы пытаетесь сделать - это экономия на спичках, которая может помочь только если у вас по настоящему высоконагруженный сервис.
P.S. если вы пишете библиотеку, которая потом будет использоваться другими проектам, то я всеми конечностями за, если вы решили заморочиться с оптимизацией.