2015-04-24 3 views
1

Я хочу создать строку JSON из объекта.Jackson writeValueAsString слишком медленно

ObjectMapper om = new ObjectMapper(); 
String str = om.writeValueAsString(obj); 

Некоторые объекты большие, и для создания строки JSON требуется много времени. Для создания строки 8MB JSON требуется около 15 секунд.

Как я могу улучшить это?

+1

Обновите свой процессор. Вот и все. Или попробуйте разные сторонние библиотеки для этой задачи. Может быть, один из них быстрее для вас – Kon

+0

Я думаю, что 15 секунд для объекта whitch занимает 8 МБ для создания, 15 секунд достаточно хорош – libik

+0

Как вы оцениваете производительность? (Я имею в виду, вы делаете тест один или несколько раз и принимаете среднее значение? С разными наборами данных или только с одним?). Вам не нужно создавать новый «ObjectMapper» для каждого запуска, если это так, см. Http://stackoverflow.com/questions/3907929/should-i-make-jacksons-objectmapper-as-static-final – BretC

ответ

1

Удостоверьтесь, что у вас достаточно памяти: Java String для хранения 8 МБ сериализованного JSON требует около 16 мегабайт смежных памяти в куче.

Но что еще более важно: почему вы создаете java.lang.String в памяти? Какое возможное использование существует для такой огромной строки?

Если вам нужно записать содержимое JSON в файл, для этого существуют разные методы; аналогично для записи в сетевой сокет. По крайней мере, вы можете написать вывод как byte[] (занимает 50% меньше памяти), но в большинстве случаев инкрементная запись во внешний поток требует очень небольшой памяти.

15 секунд, безусловно, очень медленно. Без проблем с GC, после первоначального разминки, Джексон должен написать 8 мегабайт за долю секунды, что-то вроде 10-20 миллисекунд для простого объекта, состоящего из стандартных типов Java.

EDIT:

Просто понял, что во время строительства строки результата, использование временной памяти будет в два раза, а также, поскольку буферизацией содержание пока не очищается, когда String построен. Таким образом, для построения String потребуется 8 Мбайт, по крайней мере, 32 МБ. С кучей по умолчанию 64 МБ это не сработает.

+0

Я изменил свою программу на использование 'om.writeValueAsBytes (obj);', но все еще нуждается в 7.3secs (вставил 'System.nanotime()' непосредственно перед/после 'om.writeValueAsBytes (obj)', а разница составляет около 7300000000) для создания 7MB JSON String. –

+0

Хорошо, пару вещей: (1) сколько кучи и (2) это сразу после запуска JVM, первого запуска или после выполнения большего количества записей? Первый запуск медленнее из-за запуска JVM, оптимизации байт-кода и т. Д. А затем также (3) какие объекты у вас есть? – StaxMan

+0

(1) 'Runtime.getRuntime(). FreeMemory()' непосредственно перед 'writeValueAsBytes' составляет около 3.4M, а сразу после этого около 31M (больше, чем раньше), (2) после записи, (3) Список объектов. Размер списка - около 5000, каждый объект имеет 40 строковых переменных. –

Смежные вопросы