Есть ли способ сказать JVM оптимизировать мой код перед обработкой? - PullRequest
4 голосов
/ 07 января 2011

У меня есть метод, который занимает много времени, чтобы выполнить в первый раз. Но после нескольких вызовов это занимает примерно в 30 раз меньше времени. Итак, чтобы мое приложение быстрее реагировало на взаимодействие с пользователем, я «разогреваю» этот метод (5 раз) некоторыми примерами данных при инициализации приложения. Но это увеличивает время запуска приложения.
Я читал, что JVM может оптимизировать и скомпилировать мой Java-код в нативный, тем самым ускоряя процесс. Я хотел знать - может быть, есть какой-то способ явно указать JVM, что я хочу, чтобы этот метод компилировался при запуске приложения?

Ответы [ 6 ]

6 голосов
/ 07 января 2011

JVM выполняет оптимизацию JiT (Just in Time) во время выполнения.Это означает, что он может анализировать, как выполняется ваш код, и вносить оптимизации для повышения производительности во время выполнения.Это происходит в время выполнения .Если вы видите, что метод становится быстрее после нескольких выполнений, это, вероятно, из-за оптимизации JiT (если ваш анализ не является ошибочным и, скажем, метод становится быстрее, потому что данные становятся проще).Если ваш анализ верен, компиляция в native может действительно повредить вам, потому что вы больше не будете получать оптимизацию во время выполнения.

Можем ли мы увидеть метод?Вы можете сделать это быстрее, не беспокоясь о том, как работает JVM.Вы должны выделить точно там, где выполняются самые дорогостоящие операции.Вы также должны убедиться, что это не какая-то проблема сбора мусора.то есть, может быть, метод в порядке, но GC работает, что жует время, и когда это сделано, ваш метод работает на приемлемых скоростях.

3 голосов
/ 09 января 2011
3 голосов
/ 07 января 2011

JIT-оптимизации работают так хорошо именно потому, что они оптимизируют то, что делает ваш код на самом деле , а не то, что может делать в разных случаях.

Это даже возможночто код JITted отличается на разных прогонах из-за разных входных данных.Или даже он может быть повторно оптимизирован несколько раз, когда обстоятельства меняются.

Другими словами: без реальных данных JVM не сможет выполнить хорошую работу по оптимизации кода.(т. е. он может выполнять только «статические» оптимизации)

Но, в конце концов, если вы получаете такое большое улучшение (30х - это много!), вполне вероятно, что это либо

  • не код, а что-то еще (например, кэш файлов или базы данных)
  • очень неоптимальный код на уровне исходного кода.(как некоторые тяжелые вычисления, которые могут выходить из узких циклов)

РЕДАКТИРОВАТЬ:

После просмотра вашего кода в большом цикле на Literas.prepareLiteras()Вы постоянно звоните path.contains(p) с разными точками, но одним и тем же путем.SimplePath.contains() создает ограничивающую фигуру каждый раз, когда она вызывается, поэтому вы в конечном итоге создаете одну и ту же форму снова и снова.Это яркий пример того, что должно быть извлечено из внутреннего цикла.

Я не думаю, что JIT может оптимизировать весь этот метод, но в некоторых крайних случаях он может преобразовать getShape() в нечтоспециализируется для одного пути и перекомпилируется снова для следующего пути.Плохое использование смартов JVM, а?

2 голосов
/ 07 января 2011

Вы можете попробовать запустить это на 64-битной JVM, если у вас 64-битная операционная система.

В реализации Oracle есть две версии JVM: клиентская виртуальная машина и серверная виртуальная машина.В 32-битной Windows клиентская виртуальная машина используется по умолчанию.В 64-битной Windows серверная виртуальная машина используется по умолчанию.

Разница между виртуальной машиной клиента и сервера заключается в том, как они настроены: виртуальная машина сервера выполняет более агрессивные оптимизации (и делает их раньше), чем клиентская.VM.Виртуальная машина сервера оптимизировала настройки для длительных процессов.У клиентской виртуальной машины есть настройки по умолчанию, которые оптимизированы для использования на настольном компьютере: она меньше оптимизирует заранее, но запускается быстрее.

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

2 голосов
/ 07 января 2011

Если вы используете Sun JVM, существуют разные пороги для JIT-компиляции, в зависимости от того, используете ли вы клиентскую или серверную JVM.Для клиента это 1500 вызовов метода, для сервера - 10000. Вы можете изменить его на очень низкое значение, используя параметр JVM -XX:CompileThreshold=100.

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

Я никогда не видел улучшения с фактором 30 при прогреве, что было связано с оптимизацией JIT.Еще.Это всегда было связано с некоторыми кешами.

1 голос
/ 07 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...