Поиск по сайту:

Что такое JIT-компиляция?


Компиляция Just-In-Time, или JIT, — это метод, используемый интерпретаторами времени выполнения для таких языков, как JavaScript, C# и Java, чтобы приблизить скорость выполнения к исходной производительности, предлагаемой предварительно скомпилированными двоичными языками, такими как C++.

Компиляторы против интерпретаторов

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

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

Однако у компиляторов есть несколько недостатков. Программы должны быть скомпилированы для определенных наборов инструкций ЦП (например, x86-64 или ARM). Кроме того, даже в операционных системах с общими наборами инструкций (таких как Windows и Linux, которые работают на процессорах Intel) программы должны быть скомпилированы отдельно из-за множества различий в том, как они работают.

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

Переводчики придерживаются другого подхода. Интерпретатор — это, по сути, программный робот, который берет исходный код программы, такой как сценарий JavaScript или Python, и обрабатывает выполнение во время выполнения. По сути, он действует как промежуточный слой между исходным кодом и машиной, находясь там, где компилятор будет напрямую его переводить.

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

Что делает JIT-компиляция?

К сожалению для переводчиков, они медленные. Настоящий интерпретатор должен преобразовывать и обрабатывать каждую отдельную инструкцию, фактически выполняя работу компилятора при каждом выполнении. Это много накладных расходов, поэтому на самом деле большинство интерпретаторов, таких как движок JavaScript V8, виртуальная машина Java (JVM) и среда выполнения Common Language Runtime .NET, используют компиляцию Just-In-Time для ускорения интерпретатора.

Компиляция Just-In-Time — это, по сути, компилятор, который откладывает и компилирует код для каждой функции только тогда, когда это необходимо. Всякий раз, когда вы вызываете функцию, если JIT-компилятор ее еще не видел, он скомпилирует эту функцию (применив любые оптимизации для машины, на которой она выполняется) и запустит ее. В следующий раз, когда вы вызовете функцию, у нее уже будет под рукой машинный код, поэтому ей просто нужно найти его в кеше.

Just-In-Time относится к тому факту, что интерпретатору не нужно компилировать все приложение сразу. Конечно, можно, но для большого приложения это приведет к очень большому времени запуска. Для производительности лучше выполнять компиляцию только тогда, когда это необходимо (т. е. как раз вовремя).

Влияет ли JIT-компиляция на производительность?

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

Однако, поскольку JIT-компиляцию обычно нужно запускать только при первом вызове функции, часто используемые функции действительно увидят снижение производительности только при первом вызове. Вы можете проверить это на C# с помощью StopWatches — они улавливают «фоновый шум» .NET, включая время, затрачиваемое на JIT-компиляцию при первом запуске функции.

Основным недостатком приложений, скомпилированных JIT, является длительное время холодного запуска, поскольку тысячи функций, вызываемых при запуске, должны быть скомпилированы прямо при запуске. Для загрузки некоторых веб-приложений ASP.NET может потребоваться более минуты, отчасти из-за высокой нагрузки на JIT-компилятор при запуске.