Каковы преимущества своевременной компиляции по сравнению с заранее компиляцией?

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

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

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

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

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


ОТРЕДАКТИРУЙТЕ Для очистки некоторого беспорядка, возможно, было бы важно указать, что я - все для промежуточного представления исполняемых файлов. Это имеет много преимуществ (и действительно, большинством аргументов в пользу своевременной компиляции являются на самом деле аргументы в пользу промежуточного представления). Мой вопрос о том, как они должны быть скомпилированы в собственный код.

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

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

68
задан N J 28 June 2015 в 03:14
поделиться

5 ответов

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

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

Исполняемые файлы, скомпилированные как раз вовремя, обычно имеют преимущество в этих случаях:

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

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

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

15
ответ дан 24 November 2019 в 14:22
поделиться

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

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

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

6
ответ дан 24 November 2019 в 14:22
поделиться
  1. Большая переносимость: Доставка (байт-код) остается Портативный

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

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

  4. Адаптация к метрикам выполнения. JIT-компилятор может не только смотреть только код и целевая система, но Также в том, как используется код. Может инструмент работает код, а также принимать решения о том, как оптимизировать По словам, например, что Значения параметров метода обычно случиться, имея.

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

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

34
ответ дан 24 November 2019 в 14:22
поделиться

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

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

Но нет такой вещи, как только языки только Jit. Передние временные компиляторы были доступны для Java на некоторое время, а совсем недавно моно познакомило его CLR. Фактически, Monotouch возможен вообще из-за компиляции AOT, поскольку в Apple App Store запрещено Non-Native Apps.

1
ответ дан 24 November 2019 в 14:22
поделиться
  1. Лучшая поддержка отражения. Это может быть сделано в принципе в предпринимаемой скомпилированной программе, но почти никогда не происходит на практике.

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

4
ответ дан 24 November 2019 в 14:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: