Производительность NDK против JAVA

Есть ли у какого-либо тела предположение, насколько быстро будет C-код с NDK с теми же вычислениями, тогда java-код? (если есть)

позволяет сказать, что я делаю вычисления X (те же вычисления) в Y секунд в java-коде.
Сколько X-расчетов я могу сделать за одни и те же Y секунд через код C в NDK?
1.2?
2.7?
любое количество догадок?

Предположим, что вычисление B = L/A + C/D (одно и то же для всех X вычислений).

EDIT:

Почему я спрашиваю об этом? потому что я считаю, что мои рамки обработки java-камеры обрабатываются C-кодом. Для больших возможностей разрешения

Ответ 1

Поскольку никто больше не хочет касаться этой темы, так как она не считает серьезной попытку ответить на нее, я пойду:

  • Java компилируется в байт-код, а байт-код компилируется в собственный код с помощью JIT.
  • C компилируется непосредственно в собственный код.

Разница действительно является дополнительным этапом компиляции, и, теоретически, java должна лучше работать, чем ваш компилятор C, и вот почему:

  • Java может вставлять статистические вычисления в сгенерированный собственный код, а затем через некоторое время восстанавливать его, чтобы оптимизировать его против текущих путей выполнения в вашем коде!

Эта последняя точка звучит потрясающе, java, однако, имеет некоторые компромиссы:

  • Для очистки памяти требуется выполнение GC
  • Это может не быть JIT-код вообще

GC копирует живые объекты и бросает всех мертвых, поскольку GC не нужно ничего делать для мертвого только для живых, GC в теории быстрее, чем обычный malloc/free loop для объектов.

Однако большинство сторонников Java забывают об одном: ничто не говорит о том, что вам нужно будет malloc/free каждый экземпляр объекта при кодировании C. Вы можете повторно использовать память, вы можете разделить блоки памяти и блоки свободной памяти, содержащие тысячи временно объектов на один ход.

С большими кучками на Java время GC увеличивается, добавляя время задержки. В некотором программном обеспечении это полностью нормально с временами сваливания во время цикла очистки GC, в других это приводит к фатальным ошибкам. Попробуйте сохранить свое программное обеспечение в соответствии с определенным количеством миллисекунд, когда происходит GC, и вы увидите, о чем я говорю.

В некоторых крайних случаях JIT может также не использовать JIT код вообще. Это происходит, когда метод JITed будет большим, 8K, если я правильно помню. Метод без JITed имеет штраф за выполнение во время работы в диапазоне 20000% (в 200 раз медленнее, чем, по крайней мере, у нашего клиента). JIT также включается, когда JVMs CodeCache начинает заполняться (если продолжить загрузку новых классов в JVM снова и снова, это может произойти и на сайте заказчика). В какой-то момент статистика JIT также уменьшила concurrency на одном 128-ядерном процессоре до практически одноядерной производительности.

В Java JIT имеет определенное количество времени для компиляции байт-кода в собственный код, нецелесообразно тратить все ресурсы ЦП для JIT, поскольку он работает параллельно с кодом, выполняющим фактически работу вашей программы. В C компилятор может работать до тех пор, пока ему нужно выплюнуть то, что, по его мнению, является самым оптимизированным кодом, который он может использовать. Это не влияет на время выполнения, где на Java оно есть.

То, что я говорю, действительно так:

  • Java дает вам больше, но вам не всегда удается, как это работает.
  • C дает вам меньше, но зависит от вас, как это работает.

Итак, чтобы ответить на ваш вопрос:

  • Выбор C над Java не ускорит вашу программу

Если вы только придерживаетесь простой математики над буфером preallocate, как компиляторы Java, так и C должны выплевывать примерно один и тот же код.

Ответ 2

Вероятно, вы не получите четкого ответа от кого-либо. Вопросы гораздо сложнее, чем кажется.

Не стоит ставить одинаковое количество полисов в OpenGL с помощью NDK или SDK. В конце концов, это то же самое, что и OpenGL. Время рендеринга polys (в пакетном режиме) на порядок увеличивает время накладных вызовов функции. Таким образом, это обычно полностью пренебрежимо.

Но как только приложение становится более сложным и выполняет некоторые серьезные вычисления (AI, Scene Graph Management, Culling, Image processing, Number crunching и т.д.), родная версия обычно будет намного быстрее.

И есть другое: кроме основной проблемы, что в настоящее время нет компиляции JIT. Нынешний dalvikvm с его компилятором кажется очень простым, без каких-либо оптимизаций - даже не самых простых!

Есть это (очень хорошее) видео: Google I/O 2009 - Написание игр в реальном времени для Android После того, как я увидел это, мне было ясно, что я обязательно использую С++ с NDK.

Например: он говорит о накладных вызовах функций "Не использовать вызовы функций". ... Итак, мы вернулись - до 1970 года и начали говорить о стоимости структурированного программирования и о преимуществах производительности использования только глобальных варсов и gotos.

Сбор мусора - настоящая проблема для игр. Поэтому вы потратите много времени, думая, как вы можете этого избежать. Даже форматирование строки создаст новые объекты. Итак, есть такие советы, как: не показывать FPS! Серьезно, если вы знаете С++, вам, вероятно, проще управлять памятью с помощью новых и удалить, чем настроить вашу архитектуру, чтобы уменьшить/избежать сборки мусора.

Кажется, что если вы хотите запрограммировать нетривиальную игру в реальном времени, вы теряете все преимущества Java. Не используйте Getters и Setters, Не используйте вызовы функций. Избегайте абстракции и т.д. СЕРЬЕЗНО?

Но вернемся к вашему вопросу: преимущество производительности NDK против SDK может быть от 0 до 1 000%. Все зависит.