Я пытаюсь лучше понять разницу. В Интернете я нашел много объяснений, но они имеют тенденцию к абстрактным различиям, а не к практическим последствиям.
Большая часть моего опыта программирования была с CPython (динамический, интерпретируемый) и Java (статический, скомпилированный). Однако я понимаю, что существуют другие виды интерпретируемых и компилируемых языков. Помимо того, что исполняемые файлы могут распространяться из программ, написанных на скомпилированных языках, есть ли какие-либо преимущества / недостатки для каждого типа? Часто я слышу, как люди утверждают, что интерпретируемые языки могут использоваться в интерактивном режиме, но я считаю, что скомпилированные языки также могут иметь интерактивные реализации, верно?
java
python
compiler-construction
programming-languages
interpreter
chimeracoder
источник
источник
Ответы:
Скомпилированный язык - это язык, в котором программа после компиляции выражается в инструкциях целевой машины. Например, операция «+» в вашем исходном коде может быть переведена непосредственно в инструкцию «ДОБАВИТЬ» в машинном коде.
Интерпретируемый язык является одним где инструкции непосредственно не выполняется на целевой машине, но вместо того, чтобы прочитать и выполнить какой - либо другой программы (которая обычно является написанной на языке родной машины). Например, та же самая операция «+» будет распознаваться интерпретатором во время выполнения, который затем будет вызывать свою собственную функцию «add (a, b)» с соответствующими аргументами, которая затем будет выполнять инструкцию «ADD» машинного кода. ,
Вы можете делать все, что можете на интерпретируемом языке, на скомпилированном языке и наоборот - оба они выполнены по Тьюрингу. Оба имеют свои преимущества и недостатки для реализации и использования.
Я собираюсь полностью обобщить (пуристы, прости меня!), Но, примерно, вот преимущества компилируемых языков:
И вот преимущества интерпретируемых языков:
Обратите внимание, что современные методы, такие как компиляция байт-кода, добавляют дополнительную сложность - здесь происходит то, что компилятор нацелен на «виртуальную машину», которая отличается от базового оборудования. Эти инструкции виртуальной машины могут быть затем скомпилированы снова на более позднем этапе, чтобы получить собственный код (например, как это делается JIT-компилятором Java JVM).
источник
Сам язык не компилируется и не интерпретируется, есть только конкретная реализация языка. Ява - прекрасный пример. Существует платформа на основе байт-кода (JVM), собственный компилятор (gcj) и интерпретатор для расширенного набора Java (bsh). Так что же такое Java сейчас? Байт-код скомпилирован, нативно скомпилирован или интерпретирован?
Другими языками, которые составляются и интерпретируются, являются Scala, Haskell или Ocaml. Каждый из этих языков имеет интерактивный интерпретатор, а также компилятор для байт-кода или машинного кода.
Поэтому классификация языков по «скомпилированным» и «интерпретированным» не имеет особого смысла.
источник
Начните думать с точки зрения: взрыва из прошлого
Когда-то давным-давно в стране жили вычислительные интерпретаторы и компиляторы. Все виды суеты возникли из-за заслуг одного над другим. Общее мнение в то время было чем-то вроде:
Между интерпретируемой программой и скомпилированной программой существовала разница в один или два порядка в производительности во время выполнения. Другие отличительные моменты, например изменчивость кода во время выполнения, также представляли некоторый интерес, но главное отличие заключалось в проблемах производительности во время выполнения.
Сегодня ландшафт развился до такой степени, что скомпилированное / интерпретированное различие в значительной степени не имеет значения. Многие скомпилированные языки обращаются к сервисам времени выполнения, которые не полностью основаны на машинном коде. Кроме того, большинство интерпретируемых языков «компилируются» в байт-код перед выполнением. Интерпретаторы байт-кода могут быть очень эффективными и конкурировать с некоторым кодом, сгенерированным компилятором, с точки зрения скорости выполнения.
Классическое отличие состоит в том, что компиляторы генерируют собственный машинный код, интерпретаторы читают исходный код и генерируют машинный код на лету, используя какую-то систему времени выполнения. Сегодня осталось очень мало классических интерпретаторов - почти все они компилируются в байт-код (или в другое полускомпилированное состояние), который затем запускается на виртуальной «машине».
источник
Крайние и простые случаи:
Компилятор создаст двоичный исполняемый файл в собственном исполняемом формате целевой машины. Этот двоичный файл содержит все необходимые ресурсы, кроме системных библиотек; он готов к работе без дальнейшей подготовки и обработки и работает как молния, потому что код является нативным кодом для процессора на целевой машине.
Интерпретатор предоставит пользователю подсказку в цикле, где он может вводить операторы или код, и при нажатии
RUN
или на эквивалент интерпретатор интерпретирует, сканирует, анализирует и интерпретативно выполняет каждую строку, пока программа не достигнет точки остановки или ошибки , Поскольку каждая строка обрабатывается сама по себе, и интерпретатор ничего не «изучает» из увиденного ранее строки, каждый раз для каждой строки предпринимается попытка преобразования понятного человеку языка в машинные инструкции, так что это медлительно. С другой стороны, пользователь может проверять и иным образом взаимодействовать со своей программой различными способами: изменение переменных, изменение кода, запуск в режимах трассировки или отладки ... что угодно.Позвольте мне объяснить, что жизнь уже не так проста. Например,
В конце концов, в наши дни интерпретация и компиляция - это компромисс: время, потраченное (один раз) на компиляцию, часто вознаграждается лучшей производительностью во время выполнения, но в среде интерпретации, предоставляющей больше возможностей для взаимодействия. Компиляция против интерпретации в основном зависит от того, как работа по «пониманию» программы распределяется между различными процессами, и в наши дни линия немного размыта, поскольку языки и продукты пытаются предложить лучшее из обоих миров.
источник
С http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages
источник
Самое большое преимущество интерпретируемого исходного кода перед скомпилированным исходным кодом - это ПОРТАТИВНОСТЬ .
Если ваш исходный код скомпилирован, вам нужно скомпилировать разные исполняемые файлы для каждого типа процессора и / или платформы, на которых вы хотите, чтобы ваша программа работала (например, один для Windows x86, один для Windows x64, один для Linux x64 и т. Д. на). Кроме того, если ваш код не полностью совместим со стандартами и не использует каких-либо платформо-зависимых функций / библиотек, вам фактически потребуется написать и поддерживать несколько баз кода!
Если ваш исходный код интерпретируется, вам нужно написать его только один раз, и он может быть интерпретирован и выполнен соответствующим интерпретатором на любой платформе! Это портативный ! Обратите внимание , что сам интерпретатор исполняемая программа , которая будет написана и составлена для конкретной платформы.
Преимущество скомпилированного кода заключается в том, что он скрывает исходный код от конечного пользователя (который может быть интеллектуальной собственностью ), поскольку вместо развертывания исходного удобочитаемого исходного кода вы развертываете неясный двоичный исполняемый файл.
источник
Компилятор и интерпретатор выполняют одну и ту же работу: перевод языка программирования на другой язык pgoramming, обычно ближе к аппаратному обеспечению, часто непосредственно исполняемый машинный код.
Традиционно «скомпилированный» означает, что этот перевод выполняется за один раз, выполняется разработчиком, а полученный исполняемый файл распространяется среди пользователей. Чистый пример: C ++. Компиляция обычно занимает довольно много времени и пытается выполнить много дорогостоящей оптимизации, чтобы результирующий исполняемый файл работал быстрее. Конечные пользователи не имеют инструментов и знаний для самостоятельной компиляции, а исполняемый файл часто должен работать на различном оборудовании, поэтому вы не можете выполнять многие аппаратные оптимизации. Во время разработки отдельный этап компиляции означает более длительный цикл обратной связи.
Традиционно «интерпретированный» означает, что перевод происходит «на лету», когда пользователь хочет запустить программу. Чистый пример: ванильный PHP. Наивный интерпретатор должен анализировать и переводить каждый фрагмент кода при каждом запуске, что делает его очень медленным. Он не может выполнять сложные, дорогостоящие оптимизации, поскольку они занимают больше времени, чем время, сэкономленное при выполнении. Но он может полностью использовать возможности оборудования, на котором он работает. Отсутствие отдельного этапа компиляции сокращает время обратной связи во время разработки.
Но в настоящее время «скомпилировано и интерпретировано» - это не черно-белая проблема, между ними есть оттенки. Наивные, простые интерпретаторы в значительной степени вымерли. Во многих языках используется двухэтапный процесс, когда высокоуровневый код транслируется в независимый от платформы байт-код (который интерпретируется гораздо быстрее). Кроме того, у вас есть «своевременные компиляторы», которые компилируют код не чаще одного раза за запуск программы, иногда кешируют результаты и даже разумно решают интерпретировать код, который выполняется редко, и проводят мощную оптимизацию для кода, который часто выполняется. Во время разработки отладчики способны переключать код внутри работающей программы даже для традиционно скомпилированных языков.
источник
Во-первых, пояснение: Java не полностью статически скомпилирована и связана как C ++. Он компилируется в байт-код, который затем интерпретируется JVM. JVM может выполнять компиляцию точно в срок на родном машинном языке, но это не обязательно.
Более того: я думаю, что интерактивность - это главное практическое отличие. Поскольку все интерпретируется, вы можете взять небольшой фрагмент кода, проанализировать и запустить его в соответствии с текущим состоянием среды. Таким образом, если бы вы уже выполнили код, который инициализировал переменную, у вас был бы доступ к этой переменной и т. Д. Это действительно подходит для таких вещей, как функциональный стиль.
Интерпретация, однако, стоит дорого, особенно если у вас большая система с большим количеством ссылок и контекста. По определению, это расточительно, потому что идентичный код, возможно, придется интерпретировать и оптимизировать дважды (хотя большинство сред выполнения имеют некоторое кэширование и оптимизации для этого). Тем не менее, вы платите за время выполнения и часто нуждаетесь в среде выполнения. Вы также с меньшей вероятностью увидите сложные межпроцедурные оптимизации, поскольку в настоящее время их производительность недостаточно интерактивна.
Следовательно, для больших систем, которые не будут сильно меняться, а для определенных языков более целесообразно предварительно скомпилировать и предварительно связать все, выполнить все возможные оптимизации. Это заканчивается очень экономичным временем выполнения, которое уже оптимизировано для целевой машины.
Что касается генерации исполняемых файлов, это не имеет к этому никакого отношения, ИМХО. Вы часто можете создать исполняемый файл из скомпилированного языка. Но вы также можете создать исполняемый файл из интерпретируемого языка, за исключением того, что интерпретатор и среда выполнения уже упакованы в исполняемый и скрыты от вас. Это означает, что вы, как правило, по-прежнему оплачиваете затраты времени выполнения (хотя я уверен, что для некоторых языков есть способы перевести все в исполняемый файл дерева).
Я не согласен с тем, что все языки можно сделать интерактивными. Некоторые языки, такие как C, настолько привязаны к машине и всей структуре ссылок, что я не уверен, что вы сможете создать полноценную полноценную интерактивную версию
источник
Практически сложно дать практический ответ, потому что разница заключается в самом определении языка. Можно создать интерпретатор для каждого скомпилированного языка, но невозможно создать компилятор для каждого интерпретируемого языка. Это очень много о формальном определении языка. Так что теоретической информатике Нобобы нравится в университете.
источник
Книга Python © 2015 Imagine Publishing Ltd, просто расстраивает разницу следующим указанием, упомянутым на странице 10, как:
источник
Компиляция - это процесс создания исполняемой программы из кода, написанного на скомпилированном языке программирования. Компиляция позволяет компьютеру запускать и понимать программу без необходимости использования программного обеспечения для ее создания. Когда программа компилируется, она часто компилируется для конкретной платформы (например, платформа IBM), которая работает с IBM-совместимыми компьютерами, но не с другими платформами (например, платформа Apple). Первый компилятор был разработан Грейс Хоппер во время работы на компьютере Harvard Mark I. Сегодня большинство языков высокого уровня будут включать свой собственный компилятор или иметь в наличии наборы инструментов, которые можно использовать для компиляции программы. Хорошим примером компилятора, используемого с Java, является Eclipse, а примером компилятора, используемого с C и C ++, является команда gcc.
источник
Краткое (неточное) определение:
Скомпилированный язык: вся программа сразу переводится в машинный код, затем машинный код запускается процессором.
Интерпретируемый язык: Программа читается построчно, и как только строка читается, машинные инструкции для этой строки выполняются ЦПУ.
Но на самом деле, немногие языки в наши дни являются чисто скомпилированными или чисто интерпретированными, часто это смесь. Более подробное описание с картинками смотрите в этой теме:
В чем разница между компиляцией и интерпретацией?
Или мой более поздний пост в блоге:
https://orangejuiceliberationfront.com/the-difference-between-compiler-and-interpreter/
источник