Почему интерпретатор с JIT выдает более быстрые коды, чем без него?

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


person Community    schedule 09.01.2012    source источник
comment
Потому что выполнение машинного языка выполняется быстрее, чем выполнение байт-кода. Байт-код — это машинный язык виртуальной машины, но он по-прежнему изменяет реальные данные в памяти. JIT позволяет собственному машинному коду выполнять те же самые операции.   -  person Dave Newton    schedule 09.01.2012
comment
Можете ли вы привести краткий пример того, как выполняется изменение реальных данных в памяти (JIT или не-JIT)?   -  person    schedule 09.01.2012
comment
Посмотрите на какой-нибудь дизассемблированный байт-код, чтобы увидеть версию без JIT. Посмотрите на какой-нибудь язык ассемблера, чтобы увидеть JIT-версию.   -  person Dave Newton    schedule 09.01.2012
comment
какие команды вы используете для получения не-JIT/JIT-версии в Java?   -  person    schedule 09.01.2012
comment
Вы не получите версию JIT (без каких-либо трудностей). javap -c дизассемблирует файл класса и показывает байт-код. Примеры языка ассемблера есть везде.   -  person Dave Newton    schedule 09.01.2012


Ответы (3)


Предположим, у вас есть цикл, который нужно выполнить миллион раз.

«Настоящий» интерпретатор должен просматривать байт-код this на каждой итерации цикла и определять, какое влияние код должен оказывать на состояние системы (вызовы и т. д.).

JIT-компилятор просматривает байт-код только один раз1 и компилирует его в машинный код, который затем может быть понят непосредственно компьютером — дальнейшая трансляция не требуется. Перевод требует времени, поэтому, если вы можете сделать это только один раз, это более эффективно.

Приведем пример из реальной жизни: если бы у вас был роман на английском языке и некоторые французы интересовались им, вы могли бы отдать книгу тому, кто знает оба языка, и кто мог бы читать ее вслух каждого человека индивидуально. Или вы можете попросить этого человека забрать книгу, перевести ее на французский язык, а затем дать каждому французу копию книги на французском языке. Если книгой интересуется только один человек, то оперативный перевод более эффективен - нет необходимости в редакторе, верстальщике, типографе и т.д... но если желающих много прочтите книгу, тогда имеет смысл сделать более тщательный разовый перевод.


1 Некоторые JIT-компиляторы, в том числе и в HotSpot, фактически JIT-компилируют один и тот же код несколько раз с разными уровнями оптимизации, в зависимости от использования.

person Jon Skeet    schedule 09.01.2012
comment
Мне нравится новый пример, который вы привели. Что касается комментария HotSpot, я предполагаю, что JIT-компиляция одного и того же кода несколько раз может стать узким местом при выполнении программы, не так ли? Интересно, насколько быстро JIT-компилятор по сравнению с опережающим компилятором при компиляции кода? - person ; 09.01.2012
comment
@tsubasa: он перекомпилирует его только тогда, когда JIT обнаружит, что он является узким местом, и решит, что, вероятно, стоит потратить еще немного времени на оптимизацию. Там много тонкостей, и иногда, конечно, ошибается, но в целом хорошо :) - person Jon Skeet; 09.01.2012
comment
+1 Новый пример кажется отличной метафорой для интерпретации VS компиляции в целом (единственная разница между JIT и AOT заключается в том, что издатели AOT переводят книги еще до того, как продают их, в то время как издатели JIT ждут и смотрят, какие переводы, вероятно, будут продаваться). - person ; 09.01.2012
comment
@JonSkeet: +1 В дополнение к вашему мнению, я думаю, что все программы в IL (например, байт-код) могут быть оптимизированы только до некоторой степени из-за присущего им более высокого уровня абстракции. Я имею в виду, поскольку байт-коды Java не предназначены для конкретной архитектуры, их нельзя оптимизировать до высокого уровня. В результате интерпретатор должен интерпретировать плохо оптимизированный код. Я прав? - person Gupta; 09.01.2012

Код, скомпилированный JIT, фактически выполняется непосредственно на «голом железе», тогда как интерпретируемый код должен постоянно переинтерпретироваться интерпретатором. Интерпретатору больше не нужно повторно обрабатывать и повторно обрабатывать байт-код.

person Mike Thomsen    schedule 09.01.2012

Компилятор переводит наш исходный код высокого уровня в байт-код, а для перевода байт-кода в машинный код некоторые реализации имеют обычный интерпретатор, некоторые — компилятор Just-in-time. Чтобы выполнить цикл, который выполняется, скажем, миллион раз, JIT-компилятор преобразует байт-код в машинный код только один раз, а в следующих итерациях машина просто понимает байт-код. В то время как обычный интерпретатор в каждой итерации многократно переводит байт-код в машинный код, что требует больше времени для завершения цикла, который выполняется, скажем, миллион раз.

person djbtalk    schedule 09.06.2021