[Java] Скомпилированные и интерпретируемые языки


Answers

Сам язык не компилируется и не интерпретируется, а только конкретная реализация языка. Java - прекрасный пример. Существует байт-кодовая платформа (JVM), собственный компилятор (gcj) и интерпретатор для надмножества Java (bsh). Итак, что такое Java сейчас? Компилируется байткод, скомпилирован или интерпретируется?

Другие языки, которые скомпилированы, а также интерпретируются, - Scala, Haskell или Ocaml. Каждый из этих языков имеет интерактивный интерпретатор, а также компилятор для байтового кода или собственный машинный код.

Так что вообще категоризация языков по «скомпилированным» и «интерпретированным» не имеет большого смысла.

Question

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

Большинство моих опытов программирования были с CPython (динамический, интерпретируемый) и Java (статический, скомпилированный). Однако я понимаю, что существуют и другие типы интерпретируемых и скомпилированных языков. Помимо того, что исполняемые файлы могут быть распространены из программ, написанных на скомпилированных языках, существуют ли какие-либо преимущества / недостатки для каждого типа? Зачастую я слышу, как люди утверждают, что интерпретируемые языки могут использоваться в интерактивном режиме, но я считаю, что скомпилированные языки могут также иметь интерактивные реализации, правильно?




Книга Python © 2015 Imagine Publishing Ltd просто расстраивает разницу следующим намеком, упомянутым на странице 10, как:

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




Во-первых, разъяснение, Java не полностью статично скомпилировано и связано с тем, как C ++. Он скомпилирован в байт-код, который затем интерпретируется JVM. JVM может идти и делать компиляцию точно в срок на родной машинный язык, но это не нужно делать.

Более того: я считаю, что интерактивность является основной практической разницей. Поскольку все интерпретируется, вы можете взять небольшой фрагмент кода, проанализировать и запустить его против текущего состояния среды. Таким образом, если вы уже выполнили код, который инициализировал переменную, у вас был бы доступ к этой переменной и т. Д. Это действительно позволяет использовать такие вещи, как функциональный стиль.

Интерпретация, однако, стоит много, особенно когда у вас есть большая система с большим количеством ссылок и контекста. По определению, это расточительно, потому что идентичный код, возможно, придется интерпретировать и оптимизировать дважды (хотя для большинства версий времени для этого есть кэширование и оптимизация). Тем не менее, вы платите за время исполнения и часто нуждаетесь в среде выполнения. Вы также менее склонны видеть сложные межпроцедурные оптимизации, поскольку в настоящее время их производительность недостаточно интерактивна.

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

Что касается генерации исполняемых команд, это мало связано с ним, IMHO. Вы часто можете создавать исполняемый файл с компилируемого языка. Но вы также можете создать исполняемый файл из интерпретируемого языка, за исключением того, что интерпретатор и среда выполнения уже упакованы в exectuable и скрыты от вас. Это означает, что вы, как правило, по-прежнему оплачиваете затраты времени исполнения (хотя я уверен, что для некоторых языков есть способы перевести все на исполняемый файл дерева).

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




Самое большое преимущество интерпретируемого исходного кода в отношении скомпилированного исходного кода - ПОРТАТИВНОСТЬ .

Если ваш исходный код скомпилирован, вам нужно скомпилировать другой исполняемый файл для каждого типа процессора и / или платформы, для которых вы хотите запустить свою программу (например, один для Windows x86, один для Windows x64, один для Linux x64 и т. Д. на). Кроме того, если ваш код не полностью совместим со стандартами и не использует какие-либо функции / библиотеки для конкретной платформы, вам действительно нужно будет писать и поддерживать несколько баз кода!

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

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




Крайние и простые случаи:

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

  • Интерпретатор представит пользователю запрос в цикле, в котором он может вводить операторы или код, а при достижении RUN или эквивалента интерпретатор будет проверять, анализировать, анализировать и интерпретировать каждую строку до тех пор, пока программа не запустится до точки остановки или ошибка. Поскольку каждая строка обрабатывается сама по себе, и интерпретатор не «учит» что-либо из того, что видел линию раньше, усилия по преобразованию удобочитаемого языка в машинные инструкции выполняются каждый раз для каждой строки, так что это собака медленная. С яркой стороны пользователь может проверять и иным образом взаимодействовать со своей программой различными способами: изменять переменные, изменять код, работать в режимах трассировки или отладки ... что угодно.

С учетом этого, позвольте мне объяснить, что жизнь не так проста. Например,

  • Многие интерпретаторы будут предварительно компилировать код, который им задан, поэтому шаг перевода не нужно повторять снова и снова.
  • Некоторые компиляторы компилируются не для машинных инструкций, специфичных для процессора, а для байт-кода, своего рода искусственный машинный код для фиктивной машины. Это делает скомпилированную программу более переносимой, но для каждой целевой системы требуется интерпретатор байт-кода.
  • В настоящее время интерпретаторы байт-кода (я смотрю на Java здесь) имеют тенденцию перекомпилировать байт-код, который они получают для центрального процессора целевого раздела непосредственно перед выполнением (называемый JIT). Чтобы сэкономить время, это часто делается только для кода, который работает часто (горячие точки).
  • Некоторые системы, которые выглядят и действуют как интерпретаторы (например, Clojure), компилируют любой код, который они получают, немедленно, но разрешают интерактивный доступ к среде программы. Это в основном удобство переводчиков со скоростью бинарной компиляции.
  • Некоторые компиляторы действительно не компилируются, они просто предварительно переваривают и сжимают код. Я немного слышал об этом, как работает Perl. Поэтому иногда компилятор просто выполняет немного работы, и большинство из них все еще интерпретируется.

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