Зачем нужен байт-код?

Я внимательно прочитал en.wikipedia.org/wiki/Bytecode.

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

Но зачем заставлять целевую машину пережёвывать байт-код посредством виртуальной машины/JIT-компилятора? Почему нельзя один раз скомпилировать под целевую архитектуру при первом запуске/обращении или при установке/деплое (Ahead-Of-Time, короче)?

Причина, по которой возник сей глупый вопрос, так же глупа и банальна: ведь программа, написанная на C, будет работать быстрее аналогичной по функционалу программы, написанной на любом интерпретируемом языке.
  • Вопрос задан
  • 8203 просмотра
Пригласить эксперта
Ответы на вопрос 2
icelaba
@icelaba
Знаю и умею всё
Особенность многих jit компиляторов в том что они умеют оптимизировать код на лету, используя статистику выполнения программы,
например hotpath оптимизация считает количество попаданий в ту или иную часть программы, и генерит машинный код только для кусков кода где программа реально часто выполняется.
Что это дает: за счет этого jit оптимизатор может разместить куски часто выполняющегося машинного кода очень близко друг к другу - так что они все целиком будут умещаться например в кэше процессора, и да - jit компилятор порой за счет этого обгоняет прекомпилированный машинный код.

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

Есть еще куча подобных оптимизаций которые реально помогают динамическим языкам работать почти наравне по скорости с С на некоторых задачах, яркий пример luajit

И до кучи динамические языки зачастую невозможно заранее перенести в native код чтобы сам этот код не прератился в некорый интерпретатор байткода, вот хорошо про это написано:
stackoverflow.com/questions/15626611/can-regular-j...

(c# кстати нединамический поэтому для него насколько я помню была какая то тулзень для прекомпиляции в native код - но я уже лет сто ;-) не писал на c# поэтому точно не помню)
Ответ написан
afiskon
@afiskon
Идея следующая. Берется программа, транслируется в платформонезависимый байткод. Затем под виртуальной машиной этот байткод можно запустить без изменений и под x86 Windows и под x64 Linux. То есть, программу не придется компилировать под каждую платформу отдельно. На самом деле я даже могу не знать о существовании некоторых платформ, на которых мою программу кто-то запустит. Возможно, этих платформ еще даже не существует.

Кроме того, при обновлении виртуальной машины байткод может быть скомпилирован в более эффективный машинный код. И вообще-то даже на двух процессорах с одной архитектурой могут быть применимы очень разные оптимизации, так что платформ в действительности сильно больше, чем количество архитектур * количество ОС.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы