Каковы преимущества just-in-time компиляции по сравнению с опережающей компиляцией?



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



Так вот они главные pro-JIT аргументы компиляции я обычно слышу:





  1. just-in-time компиляция обеспечивает большую переносимость. разве это не связано с промежуточный формат? Я имею в виду, что ничто не мешает вам компилировать свой виртуальный байт-код в собственный байт-код, как только вы его получите на своей машине. Переносимость является проблемой на этапе "распределения", а не на этапе "запуска".


  2. ладно, тогда как насчет генерации кода во время выполнения? Ну, то же самое относится. Ничто не удерживает вас от интеграции "точно в срок" компилятор для реального времени нужна на ваш родной программы.


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


не нравится будущее время компиляция также не имела никаких преимуществ. времени компиляция имеет временные ограничения: вы не можете заставить конечного пользователя ждать вечно пока ваша программа запускается, поэтому у нее есть компромисс, чтобы сделать где-то. Большую часть времени они просто оптимизируют меньше. У моего друга был профилирование доказательств что встраивание функций и разворачивание циклов "вручную" (запутывание исходного кода в процессе работы) оказало положительное влияние на производительность его C# номер-хруст программы; делать то же самое на моей стороне, с моим C программа, заполняющая ту же задачу, не дала никаких положительных результатов, и я считаю, что это связано с обширные преобразования мой компилятор было разрешено сделать.



и все же мы окружены jitted программами. C# и Java везде, скрипты Python могут компилироваться в какой-то байт-код, и я уверен, что целая куча других языков программирования делает то же самое. Должна быть веская причина, по которой я пропал. Так что же делает времени компиляция настолько превосходил будущее время компиляция?





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



большинство сред выполнения (или компиляторов, если на то пошло) предпочтут либо скомпилируйте их точно в срок или заранее. Как будущее время компиляция выглядит как лучшая альтернатива для меня, потому что компилятор имеет больше времени для выполнения оптимизации, мне интересно, почему Microsoft, Sun и все остальные идут по другому пути. Я немного сомневаюсь в оптимизации, связанной с профилированием, так как мой опыт работы с времени скомпилированные программы показали плохую базовую оптимизацию.



Я использовал пример с кодом C только потому, что я нужен пример будущее время компиляция против времени компиляции. Дело в том, что C код не был отправлен в промежуточное представление не имеет отношения к ситуации, так как мне просто нужно было показать, что будущее время компиляция может дать лучшие немедленные результаты.

802   9  

9 ответов:

  1. большой мобильность: результат (байт-код) остается портативный

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

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

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

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

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

The страница инструмента ngen пролил бобы (или, по крайней мере, обеспечил хорошее сравнение собственных изображений с JIT-скомпилированными изображениями). Исполняемые файлы, которые компилируются заранее, как правило, имеют следующие преимущества:

  1. образы в машинном коде загружаются быстрее, потому что они не имеют много операций запуска и требуют статического объема меньше памяти (память, требуемая JIT-компилятором);
  2. собственные изображения могут совместно использовать код библиотеки, в то время как JIT-компилируется изображения не могут.

just-in-time compiled executables обычно имеют преимущество в этих случаях:

  1. собственные изображения больше, чем их аналог байт-кода;
  2. образы в машинном коде должны быть восстановлены при каждом изменении исходной сборки или одной из ее зависимостей.

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

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

простая логика говорит нам, что компиляция огромной программы размера MS Office даже из байт-кодов просто займет слишком много времени. Вы будете в конечном итоге с огромным временем начала, и это отпугнет любого от вашего продукта. Конечно, вы можете скомпилировать во время установки, но это также имеет свои последствия.

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

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

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

  2. оптимизации, которые часто могут быть вычислены только путем динамического наблюдения за программой. Например, встраивание виртуальных функций, экранирование анализа для превращения распределения стека в распределение кучи и укрупнение блокировки.

одно из преимуществ JIT, которое я не вижу здесь, - это возможность встроить / оптимизировать через отдельные сборки / DLL / jars (для простоты я просто собираюсь использовать "сборки" отсюда).

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

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

похоже, что эта идея была реализована на языке Dart:

https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

JIT-компиляции во время разработки, используя компилятор, который особенно быстро. Затем, когда приложение готово к выпуску, оно компилируется AOT. Следовательно, с помощью передовых инструментов и компиляторов Dart может обеспечить лучшее из обоих миров: чрезвычайно быстрые циклы разработки и быстрый время выполнения и запуска.

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

те времена давно прошли. При использовании языка сценариев такие как PHP или JavaScript, вы можете проверить любое изменение немедленно. Это не так с Java, хотя appservers дает вам горячее развертывание. Так что это просто очень удобно, что Java-программы могут быть составлен быстро, поскольку компиляторы байт-кода довольно просты.

но, нет такой вещи, как JIT-только языки. опережающие компиляторы были доступны для Java в течение довольно долгого времени, и совсем недавно Mono представил его в CLR. В факт, есть некоторые подробности возможно вообще из-за компиляции AOT, так как неродные приложения запрещены в магазине приложений Apple.

Я также пытался понять это, потому что я видел, что Google движется к замене своей виртуальной машины Dalvik (по сути, другой виртуальной машины Java, такой как HotSpot) на Android Run Time (ART), который является компилятором AOT, но Java обычно использует HotSpot, который является JIT-компилятором. По-видимому, ARM ~ 2x быстрее, чем Dalvik... поэтому я подумал про себя: "почему Java не использует AOT?". В любом случае, из того, что я могу собрать, главное отличие заключается в том, что JIT использует адаптивный оптимизация во время выполнения, которая (например) позволяет компилировать в машинный код только те части байт-кода, которые выполняются часто; в то время как AOT компилирует весь исходный код в машинный код, а код меньшего объема выполняется быстрее, чем код большего объема.
Я должен представить, что большинство приложений для Android состоят из небольшого количества кода, поэтому в среднем имеет смысл скомпилировать весь исходный код в собственный код AOT и избежать накладных расходов связанный с интерпретацией / оптимизацией.

разница между platform-browser-dynamic и platform-browser заключается в том, как будет скомпилировано ваше угловое приложение. Использование динамической платформы делает угловую отправку компилятора Just-In-Time на передний конец, а также ваше приложение. Это означает, что ваше приложение компилируется на стороне клиента. С другой стороны, использование платформы-браузера приводит к тому, что заранее скомпилированная версия вашего приложения отправляется в браузер. Что обычно означает значительно меньший пакет отправляется в браузер. Angular2-документация для начальной загрузки в https://angular.io/docs/ts/latest/guide/ngmodule.html#! # bootstrap объясняет это более подробно.

Comments

    Ничего не найдено.