Я унаследовал фрагмент кода, который интенсивно использует преобразования String -> byte [] и наоборот для некоторого домашнего кода сериализации. По сути, объекты Java знают, как преобразовать свои составные части в строки, которые затем преобразуются в байты []. Затем указанный массив байтов передается через JNI в код C++, который восстанавливает байт [] в std :: strings в C++ и использует их для загрузки объектов C++, которые отражают объекты Java. Это немного больше, но это высокий уровень представления о том, как работает этот кусок кода; Связь работает так в обоих направлениях, что переход C++ -> Java является зеркальным отображением перехода Java -> C++, о котором я упоминал выше.Любое предложение о том, как повысить производительность преобразования строки Java в байт []?
Одна часть этого кода - фактическое преобразование строки в байт [] - неожиданно появляется в профилировщике как сжигание большого количества CPU. Конечно, есть много данных, которые передаются, но это неожиданное узкое место.
Основной контур кода выглядит следующим образом:
public void convertToByteArray(String convert_me, ByteArrayOutputStream stream)
{
stream.write(convert_me.getBytes());
}
Существует немного больше функции, но не так много. Вышеупомянутая функция вызывается один раз для каждого объекта String/Stringified, и после того, как все составляющие записываются в ByteArrayOutputStream, ByteArrayOutputStream преобразуется в байт []. Развернув вышеприведенную версию в более профилирующую версию, извлекая вызов convert_me.getBytes()
, показано, что более 90% времени в этой функции расходуется на вызов getBytes().
Есть ли способ улучшить производительность вызова getBytes() или есть другой, потенциально более быстрый способ добиться такого же преобразования?
Число объектов, которые преобразуются, довольно велико. На прогонах профилирования, которые используют только небольшое подмножество производственных данных, я вижу примерно 10 миллионов плюс звонки в вышеупомянутую функцию преобразования.
В связи с тем, что мы очень близки к выпуску проект в производство, есть несколько обходных путей, которые не возможно в данный момент времени:
- Перепишите интерфейс сериализации просто пройти Строковые объекты на уровне JNI. Это очевидный (для меня) способ улучшения ситуации, но для этого потребуется серьезная реинжиниринг уровня сериализации. Учитывая тот факт, что мы собираемся в UAT в начале этой недели, слишком поздно сделать такие сложные изменения. Это мой топ-todo для следующего релиза, так что это будет сделано; Тем не менее, мне нужно обходное решение до тех пор, но пока код работает, он использовался много лет и имеет большинство изломов. Ну, кроме выступления.
- Изменение JVM (в настоящее время 1,5) также не является вариантом. К сожалению, это JVM по умолчанию, установленный на компьютерах клиента, и, к сожалению, невозможно обновить до версии 1.6 (что может быть или не быть быстрее в этом случае). Любой, кто работал в крупных организациях, вероятно, понимает, почему ...
- В дополнение к этому мы уже сталкиваемся с ограничениями памяти, поэтому пытаемся кэшировать по крайней мере более крупные строки и их представление массива байтов, будучи потенциально изящным решением , скорее всего вызовет больше проблем, чем он решит
Привет Timo, просто глупый вопрос, какой профайлер инструмент вы используете? –
@Castanho - Я использовал PurifyPlus от IBM Rational. –