получить лучшую производительность при добавлении строк, чем при использовании стандартного Java stringbuilder.append - PullRequest
0 голосов
/ 17 ноября 2009

как часть процесса заполнения поисковой системы, я также заполняю хранилище значений Berekely-DB. Этот процесс повторяется каждую ночь, и в настоящий момент +/- 60% от общего времени работы каждую ночь вызвано созданием значений, которые будут вставлены в хранилище значений (таким образом, исключая фактическую вставку в Berekely-DB и вызванное время клиентом Berekely

Эти значения создаются путем назначения строителя строк каждому ключу и добавления в среднем около 1000 строк к такому строителю строк. Результирующие значения в среднем около 10к. Мне интересно, если это можно сделать более эффективно, учитывая, что: - (в среднем) 1000 строк, добавляемых к каждому из Stringbuilders, имеют фиксированную длину: то есть: каждая строка имеет одинаковую длину, и эта длина известна заранее) - все строки добавляются в конец.

Будет ли, например, замена строителя строк на char [] или characterStream / writer более производительной? Таким образом, я мог бы хранить и указывать, куда писать в char [].

Спасибо, Герт-Ян

Ответы [ 4 ]

5 голосов
/ 17 ноября 2009

Вы можете создавать свои строители строк с более высокой начальной емкостью, чтобы уменьшить объем изменения размера, то есть есть конструктор, который позволяет вам сказать

int SIZE=10000;
StringBuilder b = new StringBuilder(SIZE);

Я ожидаю, что ручное жонглирование char [] и индексов не сильно улучшится, поскольку (я полагаю) это то, что StringBuilder уже делает для вас.

0 голосов
/ 18 ноября 2009

Редакция III:

Если объединение строк в StringBuilders занимает слишком много времени, возможно, ваш память очень полная. Таким образом, наша цель - добиться объединения строк без разжевывания. до много памяти. Надеемся, что экономия процессорного времени последует автоматически.

Мой план состоял в следующем: вместо объединения этих подстрок в длинную StringBuilder, вы можете создать список ссылок на них (ранее существовавший) Строки. Список литературы должен быть короче, чем сумма подстрок и, следовательно, потребляют меньше памяти.

Только когда приходит время хранить эту большую строку, мы объединяем части в одном большом StringBuilder вытащите строку, сохраните строку, выбросьте ссылка на строку, очистить StringBuilder, повторить. Я чувствовал, что это было блестящее решение!

Однако из эта статья 2002 , ссылка на строку в массиве, вероятно, также в ArrayList, занимает колоссальные 8 байтов! Недавнее сообщение StackOverflow подтвердило, что это все еще так. Таким образом, список ссылки на 10-байтовые строки экономят только 2 байта на строку. Таким образом, я представляю «решение» как возможность для подобных проблем, но я не вижу этого конкретного проблема в том, чтобы извлечь из этого пользу.

0 голосов
/ 18 ноября 2009

Вы должны попробовать веревки . Сайт скудный по деталям, но есть отличная статья здесь с лучшим описанием и некоторыми хорошими тестами, сравнивающими производительность при добавлении .

Я на самом деле не использовал пакет с веревками, у меня не было достаточно веских оправданий. Тем не менее, выглядит многообещающе.

Редактировать: Дополнительная информация о тесте

Я скачал класс PerformanceTest из статьи о веревках и добавил тесты для StringBuilder в дополнение к StringBuffer. Улучшение производительности на StringBuilder кажется незначительным.

Я скачал тестовый код из статьи о веревках и изменил тест, включив в него StringBuilder и StringBuffer.

Append plan length: 260
[StringBuilder] Average=     117,146,000 ns Median=     114,717,000ns
[StringBuffer]  Average=     117,624,400 ns Median=     115,552,000ns
[Rope]          Average=         484,600 ns Median=         483,000ns

Append plan length: 300
[StringBuilder] Average=     178,329,000 ns Median=     178,009,000ns
[StringBuffer]  Average=     217,147,800 ns Median=     216,819,000ns
[Rope]          Average=         252,800 ns Median=         253,000ns

Append plan length: 500
[StringBuilder] Average=     221,356,200 ns Median=     214,435,000ns
[StringBuffer]  Average=     227,432,200 ns Median=     219,650,000ns
[Rope]          Average=         510,000 ns Median=         507,000ns

Разница между StringBuilder и StringBuffer не так уж велика. Для поставленной задачи Веревки кажутся здесь чистой победой.

0 голосов
/ 17 ноября 2009

Откуда взялись эти 1000 строк? Мне трудно поверить, что время создания этих 1000 объектов не полностью затмевает время, необходимое для амортизированного расширения вашего StringBuilder.

...