JIT срабатывает ПОСЛЕ того, как определенный фрагмент кода был выполнен много раз.
HotSpot JVM попытается определить «горячие точки» в вашем коде. Горячие точки — это части вашего кода, которые выполняются много раз. Для этого JVM будет «подсчитывать» выполнение различных инструкций, и когда она определяет, что определенная часть выполняется часто, она запускает JIT. (это приближение, но это легко понять, объясненное таким образом).
JIT (Just-In-Time) берет этот фрагмент кода и пытается сделать его быстрее.
Техник, используемых JIT для ускорения работы вашего кода, много, но одна из них, которая чаще всего создает путаницу:
- Он попытается определить, используются ли в этом фрагменте кода переменные, которые больше нигде не используются (бесполезные переменные), и удалит их.
- Если вы получаете и снимаете одну и ту же блокировку несколько раз (например, вызываете синхронизированные методы одного и того же объекта), он может получить блокировку один раз и выполнять все вызовы в одном синхронизированном блоке.
- Если вы обращаетесь к членам объекта, которые не объявлены volatile, он может принять решение об их оптимизации (размещение значений в регистрах и т.п.), создавая странные результаты в многопоточном коде.
- Он будет встраивать методы, чтобы избежать затрат на вызов.
- Он преобразует байт-код в машинный код.
- Если петля совершенно бесполезна, ее можно полностью удалить.
Итак, правильный ответ на ваш вопрос заключается в том, что пустой цикл после JIT-компиляции не требует времени для выполнения ... скорее всего, его больше нет.
Опять же, есть много других оптимизаций, но, по моему опыту, именно эти создают больше всего головной боли.
Более того, JIT совершенствуется в любой новой версии Java, а иногда даже немного отличается в зависимости от платформы (поскольку в какой-то степени зависит от платформы). Оптимизации, сделанные JIT, трудно понять, потому что обычно вы не можете найти их с помощью javap и проверки байт-кода, даже если в последних версиях Java некоторые из этих оптимизаций были перенесены непосредственно в компилятор (например, начиная с Java 6 компилятор способен обнаруживать и предупреждать о неиспользуемых локальных переменных и закрытых методах).
Если вы пишете несколько циклов для проверки чего-либо, обычно хорошей практикой является размещение цикла внутри метода, вызов метода несколько раз ДО того, как он засечет время, чтобы дать ему "ускорение" раунда, а затем выполнить цикл по времени.
Это обычно запускает JIT в простой программе, такой как ваша, даже если нет гарантии, что она действительно запустится (или что она вообще существует на определенной платформе).
Если вы хотите стать параноиком по поводу времени JIT или не JIT (я так и сделал): сделайте первый раунд, синхронизируя каждое выполнение цикла, и подождите, пока время не стабилизируется (например, разница со средним значением менее 10%), тогда начните с вашего «реального» времени.
person
Simone Gianni
schedule
01.09.2011
System.nanoTime()
больше подходит для этих тестов (клиент/серверная виртуальная машина также должна иметь некоторое значение) - person user85421   schedule 01.09.2011