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

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

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

Ответ 1

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

Интерпретируемый язык - это тот, где инструкции не выполняются непосредственно на целевой машине, а вместо этого считываются и исполняются какой-либо другой программой (которая обычно записывается на языке родной машины). Например, одна и та же операция "+" была бы распознана интерпретатором во время выполнения, которая затем вызывала бы свою собственную функцию "добавить (a, b)" с соответствующими аргументами, которая затем выполняла бы инструкцию "ADD" машинного кода.

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

Я собираюсь полностью обобщить (пуристы прощают меня!), но, грубо говоря, вот преимущества скомпилированных языков:

  • Более быстрая производительность путем непосредственного использования собственного кода целевой машины
  • Возможность применения довольно мощных оптимизаций на этапе компиляции

И вот преимущества интерпретируемых языков:

  • Легче реализовать (писать хорошие компиляторы очень сложно!!)
  • Не нужно запускать этап компиляции: можно выполнить код непосредственно "на лету"
  • Может быть более удобным для динамических языков

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

Ответ 2

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

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

Так что вообще категоризация языков с помощью "скомпилированных" и "интерпретируемых" не имеет особого смысла.

Ответ 3

Начните думать в терминах: взрыва из прошлого

Давным-давно давно жил в земле вычислительной техники переводчиков и компиляторов. Всевозможные проблемы возникли по существу один над другим. Общее мнение в то время было чем-то вроде:

  • Интерпретатор: быстро развивается (редактируется и запускается). Медленное выполнение, потому что каждое утверждение должно быть интерпретировано в машинный код каждый раз, когда он был выполнен (подумайте, что это означало для цикла, выполняемого тысячи раз).
  • Компилятор: медленно разрабатывать (редактировать, компилировать, связывать и запускать. Шаги компиляции/ссылки могут занять серьезное время). Быстро выполнить. Вся программа уже находилась в собственном машинном коде.

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

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

Классическое различие заключается в том, что компиляторы генерируют собственный машинный код, интерпретаторы читают исходный код и сгенерированный машинный код "на лету" с использованием какой-то системы времени выполнения. Сегодня осталось очень мало классических переводчиков - почти все из них скомпилировать в байтовый код (или некоторое другое полукомпилированное состояние), которое затем запускается на виртуальной "машине".

Ответ 4

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

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

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

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

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

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

Ответ 5

Из http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages

Нет никакой разницы, потому что "скомпилированный язык программирования" и "интерпретируемый язык программирования" arent осмысленные понятия. Любые язык программирования, и я действительно имею в виду любой, может быть истолкован или скомпилирован. Таким образом, интерпретация и компиляция являются реализацией методы, а не атрибуты языков.

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

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

Возможно, вы, возможно, предположили, что эти два определения методы внедрения не являются взаимоисключающими и могут даже быть дополняют друг друга. Традиционно язык объектов компилятора был машинный код или что-то подобное, что относится к любому числу Языки программирования, понятные конкретным компьютерным ЦП. машинный код затем будет запускаться "на металле" (хотя можно увидеть, если один выглядит достаточно внимательно, что "металл" очень похож на переводчик). Однако сегодня очень часто используется компилятор для генерировать объектный код, который должен интерпретироваться, например, этот как работает Java (и иногда все еще работает). Есть компиляторы, которые переводят другие языки на JavaScript, а затем часто запускаются в веб-браузере, которые могут интерпретировать JavaScript, или скомпилировать его виртуальную машину или собственный код. У нас также есть переводчики для машинного кода, который может использоваться для эмуляции одного вида оборудования на другой. Или можно использовать компилятор для генерации объектного кода, который то исходный код для другого компилятора, который может даже компилироваться код в памяти как раз вовремя для его запуска, что в свою очередь., Вы получаете идея. Существует много способов сочетания этих понятий.

Ответ 6

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

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

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

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

Ответ 7

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

Традиционно "скомпилированный" означает, что этот перевод происходит всего за один раз, выполняется разработчиком, и полученный исполняемый файл распространяется среди пользователей. Чистый пример: С++. Компиляция обычно занимает довольно много времени и пытается сделать много дорогостоящей optmization, так что полученный исполняемый файл работает быстрее. У конечных пользователей нет инструментов и знаний для компиляции самого материала, и исполняемый файл часто должен запускаться на различных аппаратных средствах, поэтому вы не можете выполнять множество оптимизаций для конкретных аппаратных средств. Во время разработки отдельный этап компиляции означает более длительный цикл обратной связи.

Традиционно "интерпретируемый" означает, что перевод происходит "на лету", когда пользователь хочет запустить программу. Чистый пример: ванильный PHP. Наивный интерпретатор должен анализировать и переводить каждый кусок кода каждый раз, когда он работает, что делает его очень медленным. Он не может выполнять сложные, дорогостоящие оптимизации, поскольку они занимают больше времени, чем время, затраченное на выполнение. Но он может полностью использовать возможности аппаратного обеспечения, на котором он работает. Отсутствие этапа компиляции разделения снижает время обратной связи во время разработки.

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

Ответ 8

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

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

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

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

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

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

Ответ 9

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

Ответ 10

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

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

Ответ 11

Компиляция - это процесс создания исполняемой программы из кода, написанного на скомпилированном языке программирования. Компиляция позволяет компьютеру запускать и понимать программу без необходимости использования программного обеспечения для ее создания. Когда программа компилируется, она часто компилируется для определенной платформы (например, платформы IBM), которая работает с совместимыми с IBM компьютерами, но не с другими платформами (например, с платформой Apple). Первый компилятор был разработан Грейс Хоппер во время работы на компьютере Гарварда Марка I. Сегодня большинство языков высокого уровня будут включать в себя собственный компилятор или имеющиеся инструменты, которые могут быть использованы для компиляции программы. Хорошим примером компилятора, используемого с Java, является Eclipse, а примером компилятора, используемого с C и С++, является команда gcc. В зависимости от того, насколько велика программа, для ее компиляции требуется несколько секунд или минут, и если при компиляции не возникают ошибки, создается исполняемый файл. Проверьте эту информацию.

Ответ 12

Различия

Переводчик:

  1. Процесс: интерпретатор выдает результат из программы. (Преобразует программу в машинный код при запуске программы) С другой стороны, в интерпретируемой программе исходным кодом обычно является программа. Программы такого типа (часто называемые скриптами) требуют интерпретатора, который анализирует команды в программе и затем выполняет их. Некоторые интерпретаторы, такие как оболочки Unix (sh, csh, ksh и т.д.), Читают и затем немедленно выполняют каждую команду, в то время как другие, такие как Perl, анализируют весь сценарий перед отправкой соответствующих инструкций машинного языка. Другие примеры интерпретируемого языка включают JavaScript и Python.

  2. Быстрая разработка (редактирование и запуск).

  3. Медленно выполняется, потому что каждый оператор должен интерпретироваться в машинный код каждый раз, когда он выполняется (подумайте, что это значило для цикла, выполняемого тысячи раз).

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

  5. Недостатком использования интерпретатора является то, что он не скрывает исходный код от конечного пользователя.

  6. Продолжает переводить программу до первой ошибки, и в этом случае она останавливается. Следовательно, отладка проста.

Составитель:

  1. Процесс: (преобразует программу в машинный код до ее запуска), пока компилятор создает программу, написанную на языке ассемблера. Затем ассемблер архитектуры превращает полученную программу в двоичный код. Язык ассемблера варьируется для каждого отдельного компьютера в зависимости от его архитектуры. Следовательно, скомпилированные программы могут работать только на компьютерах, имеющих ту же архитектуру, что и компьютер, на котором они были скомпилированы. Скомпилированная программа не предназначена для чтения человеком, а написана на машинном языке для конкретной архитектуры. Создание скомпилированной программы требует нескольких шагов. Во-первых, программист, используя инструмент разработки или даже простой текстовый редактор, пишет исходный код на выбранном компьютерном языке. Если программа сложная, ее части могут быть распределены по нескольким файлам. Затем программист компилирует программу, сортирует и связывает модули и переводит все это в машинный код, понятный компьютеру. Поскольку различные типы компьютеров не говорят на машинных языках друг друга, скомпилированная программа будет работать только на той платформе, для которой она была разработана. Например, программа, написанная для HP-UX, обычно не будет работать на компьютере Mac OS или компьютере, на котором установлен Solaris.

  2. Медленно разрабатывать (редактировать, компилировать, связывать и запускать. Шаги компиляции/линковки могут занять много времени).

  3. Быстро выполнить. Вся программа уже была на родном машинном коде.

  4. Скомпилированная программа будет работать только на той платформе, для которой она была разработана. Это не портативный

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

  6. Он генерирует сообщение об ошибке только после сканирования всей программы. Следовательно, отладка сравнительно сложна.

Источники: * https://kb.iu.edu/d/agsz * Различные ответы в этом посте