Я только что добавил немного дорогостоящего кода в Android-игру, которую я разрабатываю.Рассматриваемый код представляет собой набор процедур обнаружения столкновений, которые вызываются очень часто (на каждой итерации игрового цикла) и выполняют большое количество вычислений.Я чувствую, что моя реализация обнаружения столкновений довольно хорошо разработана и настолько быстра, насколько я могу сделать это на Java.
Я использовал Traceview для профилирования кода, и этот новый фрагмент кода обнаружения столкновений несколько удивительно удвоил продолжительность моей игровой логики.Это, очевидно, вызывает беспокойство, поскольку для некоторых устройств этот скачок производительности может вывести мою игру из игрового состояния в неиграбельное.
Я рассматривал различные способы оптимизации этого кода, и мне интересно, перемещать ли кодв C ++ и доступ к нему с помощью JNI, если я получу заметное снижение производительности?
Вышеуказанный вопрос - моя главная проблема и причина, по которой я спрашиваю.Я определил, что две следующие причины будут другими положительными результатами от использования JNI.Однако этого недостаточно, чтобы убедить меня перенести мой код на C ++.
Это сделает код чище.Поскольку большая часть обнаружения столкновений является своего рода векторной математикой, гораздо удобнее использовать перегруженные операторы, чем использовать более подробные векторные классы в Java.
Управление памятью будетбудь проще.Проще сказать?Что ж, это игра, поэтому запуск сборщика мусора нежелателен, поскольку сборщик мусора может в конечном итоге испортить производительность вашей игры, если ему постоянно приходится прерывать работу для очистки.В CI не нужно беспокоиться о сборщике мусора, поэтому я могу избежать всех отвратительных вещей, которые я делаю в Java с временными статическими переменными, и просто положиться на старую старую память C ++
Как ни крути вопрос, думаю, я рассмотрел все свои вопросы.Учитывая эту информацию, стоило бы переносить мой код с Java на C ++ и обращаться к нему с помощью JNI (по соображениям повышения производительности)?Кроме того, есть ли способ измерить или оценить потенциальное увеличение производительности?
РЕДАКТИРОВАТЬ:
Итак, я сделал это.Результаты?Что ж, с точки зрения TraceView, скорость моей процедуры обнаружения столкновений увеличилась в 6 раз.
Хотя добраться туда было нелегко.Помимо необходимости танцевать JNI, я также должен был сделать некоторые оптимизации, которые я не ожидал.Главным образом, использование непосредственно выделенного плавающего буфера для передачи данных из Java в native.Моя первоначальная попытка просто использовала массив float для хранения данных, потому что преобразование из Java в C ++ было более естественным, но это было действительно очень медленно.Прямой буфер полностью обошел проблемы с производительностью при копировании массива между java и native, и у меня остался 6-кратный удар.
Кроме того, вместо того, чтобы использовать свой собственный векторный класс, я просто использовал библиотеку математики Эйгена.Я не уверен, насколько это повлияло на производительность, но, по крайней мере, это сэкономило мне время на разработку моего собственного (менее эффективного) векторного класса.
Еще один урок заключается в том, чточрезмерное ведение журнала отрицательно сказывается на производительности (это не очевидно).