В чем разница между компилируемым и интерпретируемым языком?

118

После прочтения некоторых материалов по этой теме я все еще не уверен, в чем разница между компилируемым языком и интерпретируемым языком. Мне сказали, что это одно из различий между Java и JavaScript. Не мог бы кто-нибудь помочь мне понять это?

SIr Codealot
источник

Ответы:

165

В чем разница между компилируемым и интерпретируемым языком?

Разница не в языке; это в реализации .

Получив это из моей системы, вот ответ:

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

  • В интерпретируемой реализации исходная программа переводится во что-то еще. Другая программа, называемая «интерпретатором», затем исследует «что-то еще» и выполняет требуемые действия. В зависимости от языка и его реализации существует множество форм «чего-то еще». От более популярного к менее популярному может быть "что-то еще"

    • Двоичные инструкции для виртуальной машины, часто называемые байт-кодом , как это делается в Lua, Python, Ruby, Smalltalk и многих других системах (этот подход был популяризирован в 1970-х годах благодаря системе UCSD P и UCSD Pascal)

    • Древовидное представление исходной программы, такое как дерево абстрактного синтаксиса, как это делается для многих прототипов или образовательных интерпретаторов.

    • Токенизированное представление исходной программы, похожее на Tcl

    • Персонажи исходной программы, как это было сделано в MINT и TRAC

Проблема усложняется тем, что байт-код можно транслировать (компилировать) в машинные инструкции . Таким образом, успешная предполагаемая реализация может в конечном итоге получить компилятор. Если компилятор работает динамически, за кулисами, его часто называют оперативным компилятором или JIT-компилятором. JIT были разработаны для Java, JavaScript, Lua и, я полагаю, для многих других языков. На этом этапе у вас может быть гибридная реализация, в которой некоторый код интерпретируется, а некоторый код компилируется.

Норман Рэмси
источник
7
Сэр, у меня следующие вопросы: 1. На каком языке написано это «что-то еще»? 2. А в контексте JavaScript менялось ли это «что-то еще» от браузера к браузеру? 3. Скажем, мой скрипт работает в Google Chrome и Internet Explorer, интерпретируется ли он одинаково в обоих браузерах?
JavaHopper 06
@Norman, это было отличное объяснение. Однако есть еще пара недоразумений. В скомпилированной реализации исходная программа преобразуется в собственные машинные инструкции. Как придешь? Я думал, например, что C после компиляции произведет ассемблерный код, который, опять же, в любом случае должен быть собран собственным ассемблером в машинный код базовой машины. Так чем же это отличается от того, что виртуальная машина (python, JVM и т. Д.) Делает то же самое в случае интерпретируемого языка?
qre0ct,
58

Java и JavaScript - довольно плохой пример для демонстрации этой разницы , потому что оба являются интерпретируемыми языками . Java (интерпретируемая) и C (или C ++) (скомпилированная) могли бы быть лучшим примером.

Почему зачеркнутый текст? Как правильно указывает этот ответ , интерпретируемый / скомпилированный - это конкретная реализация языка, а не язык как таковой . Хотя утверждения вроде «C - это компилируемый язык» в целом верны, ничто не мешает кому-то написать интерпретатор языка C. На самом деле интерпретаторы для C существуют .

По сути, скомпилированный код может выполняться непосредственно процессором компьютера. То есть исполняемый код указывается на «родном» языке ЦП (языке ассемблера ).

Однако код интерпретируемых языков должен быть переведен во время выполнения из любого формата в машинные инструкции ЦП. Этот перевод выполняется переводчиком.

Другими словами , на интерпретируемых языках код переводится в машинные инструкции шаг за шагом во время выполнения программы, в то время как на скомпилированных языках код транслируется перед выполнением программы.

stakx - больше не участвует
источник
8
Java интерпретируется? Из википедии: «Приложения Java обычно компилируются в байт-код (файл класса), который может работать на любой виртуальной машине Java (JVM), независимо от архитектуры компьютера».
Personman
6
@Personman, который все еще технически «интерпретируется», поскольку JVM выполняет код, а не сама ОС. Это действительно семантическая разница, поскольку можно сказать, что сложность современных операционных систем не имеет значения для большинства ситуаций. Вы говорите о разнице между ОС, в которой запущено приложение, и ОС, в которой запущено приложение, в котором выполняется код.
GrayWizardx
5
Я полагаю, вы имеете в виду, что сами файлы классов интерпретируются виртуальной машиной Java. Это довольно разумно, но исходный код Java действительно компилируется в байт-код Java VM. Вы можете построить физическую Java-машину, которая не требует, чтобы виртуальная машина интерпретировала ее в машинный код другой архитектуры. Так что правильнее сказать, что Java скомпилирована. Тем не менее, это хороший пример того, как это различие сбивает с толку и отчасти произвольно. В конце концов, скомпилированный C интерпретируется процессором, верно?
Personman
13
Java - довольно плохой пример компилируемого или интерпретируемого языка, потому что по сути это и то, и другое. Если бы я собирался провести сравнение, я бы выбрал C и Lisp, чтобы избежать путаницы.
Bill the Lizard
7
@stakx - на самом деле байт-коды Java обычно компилируются в собственный код также JIT-компилятором. Единственный способ добиться чистого поведения интерпретатора - это явно выключить JIT-компилятор при запуске JVM.
Stephen C
15

Вот основная разница между компилятором и языком интерпретатора.

Язык компилятора

  • Принимает всю программу как единый вход и преобразует ее в объектный код, который хранится в файле.
  • Создается промежуточный объектный код
  • например: C, C ++
  • Скомпилированные программы работают быстрее, потому что компиляция выполняется перед выполнением.
  • Требование к памяти больше связано с созданием объектного кода.
  • Ошибка отображается после компиляции всей программы
  • Исходный код --- Компилятор --- Машинный код --- Вывод

Язык переводчика:

  • Принимает одну инструкцию как один ввод и выполняет инструкции.
  • Промежуточный объектный код НЕ генерируется
  • например: Perl, Python, Matlab
  • Интерпретируемые программы работают медленнее, потому что компиляция и выполнение происходят одновременно.
  • Требование к памяти меньше.
  • Ошибка отображается для каждой отдельной инструкции.
  • Исходный код --- Интерпретатор --- Вывод
PGOEL
источник
5

Как правило, компилятор читает компьютерный код на языке более высокого уровня и преобразует его либо в p-код, либо в собственный машинный код. Интерпретатор запускается непосредственно из p-кода или интерпретируемого кода, такого как Basic или Lisp. Как правило, скомпилированный код выполняется намного быстрее, более компактен и уже обнаружил все синтаксические ошибки и многие ошибки недопустимых ссылок. Интерпретируемый код находит такие ошибки только после того, как приложение пытается интерпретировать затронутый код. Интерпретируемый код часто хорош для простых приложений, которые будут использоваться только один или максимум пару раз, или, возможно, даже для прототипирования. Скомпилированный код лучше подходит для серьезных приложений. Компилятор сначала принимает всю программу, проверяет наличие ошибок, компилирует ее, а затем выполняет. В то время как интерпретатор делает это построчно, поэтому он берет одну строку, проверяет ее на наличие ошибок,

Если вам нужна дополнительная информация, просто введите в Google запрос «разница между компилятором и интерпретатором».

Salil
источник
3
Умм, не знаю, где вы взяли что-то из этого, помимо первых двух утверждений. Технически это было верно несколько поколений назад со многими интерпретируемыми языками, но в зависимости от платформы и внимания к деталям можно получить интерпретируемый код, который работает близко или так же хорошо, как скомпилированный код для определенных действий.
GrayWizardx
Учитывая, что такие языки, как Java, C # и JavaScript, которые сегодня почти наводняют весь мир программирования, было бы несправедливо утверждать, что «скомпилированный код лучше для серьезных приложений».
Sisir
2

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

Однако большинство языков используются в основном в той или иной форме, и да, Java по сути всегда компилируется, тогда как javascript всегда интерпретируется.

Компилировать исходный код означает запустить на нем программу, которая генерирует двоичный исполняемый файл, который при запуске имеет поведение, определенное источником. Например, javac компилирует файлы .java, читаемые человеком, в машиночитаемые файлы .class.

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

Personman
источник
Хотя Java сначала преобразует в байт-код, и только во время выполнения JVM преобразует его в машинный код; правильно ли сказать, что он компилируется, а не интерпретируется?
Sisir
1
Я думаю, вы можете сказать, что байт-код Java, конечно, интерпретируется, но никто не пишет байт-код Java. Сама Java обычно компилируется в байт-код.
Personman
2

Интерпретируемый язык выполняется во время выполнения в соответствии с инструкциями, например, в сценариях оболочки, а скомпилированный язык - это язык, который компилируется (изменяется на язык ассемблера, который может понимать процессор), а затем выполняется, как в C ++.

Правин Кишор
источник
0

Как уже говорили другие, скомпилированные и интерпретируемые специфичны для реализации языка программирования; они не присущи языку. Например, есть интерпретаторы C.

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

Во-первых, мы должны без двусмысленности определить интерпретаторы и компиляторы:

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

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

Обратите внимание, что с точки зрения программиста процессоры являются машинными интерпретаторами для своего родного машинного языка.

Теперь мы можем сделать предварительную классификацию языков программирования на 3 категории в зависимости от наиболее распространенной реализации:

  • Жестко скомпилированные языки: когда программы полностью скомпилированы на машинный язык. Единственный используемый интерпретатор - это ЦП. Пример: Обычно для запуска программы на C исходный код компилируется на машинный язык, который затем выполняется центральным процессором.
  • Интерпретируемые языки: когда нет компиляции какой-либо части исходной программы на машинный язык. Другими словами, новый машинный код не генерируется; выполняется только существующий машинный код. Также должен использоваться интерпретатор, отличный от CPU (обычно программа). Пример: в канонической реализации Python исходный код сначала компилируется в байт-код Python, а затем этот байт-код выполняется CPython, программой-интерпретатором для байт-кода Python .
  • Мягко скомпилированные языки: когда используется интерпретатор, отличный от ЦП, но также части исходной программы могут быть скомпилированы на машинный язык. Это случай Java, где исходный код сначала компилируется в байт-код, а затем байт-код может интерпретироваться интерпретатором Java и / или далее компилироваться JIT-компилятором.

Иногда мягко и жестко скомпилированные языки называются просто скомпилированными, поэтому C #, Java, C, C ++ считаются скомпилированными.

В рамках этой категоризации JavaScript раньше был интерпретируемым языком, но это было много лет назад. В настоящее время в большинстве основных реализаций JavaScript он JIT-компилируется на собственный машинный язык, поэтому я бы сказал, что он попадает в языки с программной компиляцией.

MrIo
источник