Интерпретированный против компилированного против позднего связывания - PullRequest
13 голосов
/ 21 мая 2010

Python компилируется в промежуточный байт-код (pyc) и затем выполняется. Итак, есть компиляция с последующей интерпретацией. Однако давние пользователи Python говорят, что Python является языком с «поздним связыванием» и что его нельзя называть интерпретируемым языком.

  1. Чем Python будет отличаться от другого интерпретируемого языка?

  2. Не могли бы вы сказать мне, что означает "позднее связывание" в контексте Python?

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

  1. Является ли Java интерпретируемым / скомпилированным языком?

  2. Чем он отличается от Python с точки зрения компиляции / исполнения?

  3. Говорят, что в Java нет "позднего связывания". Это как-то связано с тем, что программы на Java чуть быстрее Python?

Было бы здорово, если бы вы могли также дать мне ссылки на места, где люди уже обсуждали это; Я хотел бы прочитать больше об этом. Спасибо.

Ответы [ 5 ]

9 голосов
/ 21 мая 2010

Чем Python будет отличаться от другого интерпретируемого языка?

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

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

Не могли бы вы сказать мне, что означает "позднее связывание" в контексте Python?

Переменные не объявлены как имеющие тип. Переменная связана с типом как можно позже - с присвоением реального объекта.

Является ли Java интерпретируемым / скомпилированным языком?

Да. Он скомпилирован в байтовые коды. Байт-коды интерпретируются. Я предпочитаю называть это истолкованным.

Однако люди (по очень непонятным причинам) не согласятся. Наличие любого вида «этапа компиляции» - пусть и минимального - всегда смущает людей. Перевод в байт-код практически не имеет отношения к реальному поведению программы во время выполнения. Некоторые люди любят говорить, что интерпретировать могут только только языки, которые полностью свободны от любого признака предварительной обработки "компиляции". Примеров этого уже не так много, поскольку многие языки переводятся из дружественного человеку текста в понятные интерпретатору байтовые коды. Даже в Applesoft Basic (еще в 80-х годах) такой перевод выполнялся по мере ввода кода.

Некоторые JVM делают JIT. Некоторые нет. Некоторые из них являются смесью. Сказать, что JVM только выполняет преобразование байт-кода JIT, неверно. Некоторые JVM делают. Некоторые нет.

Чем он отличается от Python с точки зрения компиляции / исполнения?

Совсем нет. Java VM может выполнять Python. [Для легко запутанного, слово «питон» в этом контексте не может означать «источник питона». Это должно означать байт-код Python.]

Говорят, что в Java нет "позднего связывания". Это как-то связано с тем, что программы на Java чуть быстрее Python?

Может быть. Java-программы часто работают быстрее благодаря JIT-компиляторам, которые переводят байт-код Java в машинный код во время выполнения.

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

На самом деле штраф за "позднюю" привязку практически отсутствует. Атрибуты и методы Python разрешаются с помощью простого поиска в словаре. Словарь представляет собой хэш; производительность довольно хорошая. Хеши для имен могут быть помещены в пул «встроенных» строковых литералов, амортизирующих стоимость вычисления хеша.

Для реального удовольствия посмотрите PyPy и RPython. Это интерпретатор Python, который может выполнять JIT-компиляцию. Вы получаете 2-х уровневый переводчик. Ваш код интерпретируется PyPy. PyPy интерпретируется RPython. 1048 **

7 голосов
/ 21 мая 2010

Позднее связывание - совсем другое понятие для интерпретации.

Строго говоря, интерпретируемый язык выполняется непосредственно из источника. Он не проходит стадию компиляции байт-кода. Путаница возникает из-за того, что программа Python является интерпретатором, но она интерпретирует байт-код, поэтому это язык байт-кода Python, который вы бы назвали «интерпретированным». Сам язык Python является скомпилированным языком.

Байт-код Java, напротив, в наши дни интерпретируется и компилируется. Он компилируется в собственный код JIT-компилятором, а затем запускается непосредственно на оборудовании.

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

3 голосов
/ 21 мая 2010

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

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

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

Однако различие между обоими не является строгим. Мы можем не только считать, что все в конечном счете интерпретируется (см. Ответ С. Лотта), но и часть кода может быть скомпилирована, декомпилирована или перекомпилирована динамически (например, JIT), что делает различие очень размытым.

Например, динамическая загрузка классов в Java относится к категории «позднее связывание»: набор классов не является фиксированным один раз для всех, и классы могут загружаться динамически. Некоторые оптимизации могут быть выполнены, когда мы знаем набор классов, но их нужно будет сделать недействительными после загрузки новых классов. То же самое происходит с возможностью обновления метода с помощью инфраструктуры отладки: JVM потребуется де-оптимизировать все сайты вызовов, где метод был встроен.

Я не знаю много о Python, но практикующие Python предпочитают, возможно, термин «поздний предел», чтобы избежать такой путаницы.

2 голосов
/ 21 мая 2010

Я думаю, что распространенное заблуждение, что Python интерпретируется во время компиляции Java, возникает из-за явного шага компиляции - вы должны запустить javac для преобразования вашего исходного файла .java в файл байт-кода .class, который можно запустить.

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

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

0 голосов
/ 21 мая 2010

время привязки - это когда имена разрешаются. Более динамичные языки имеют тенденцию к позднему связыванию. Это может быть отдельным от интерпретации / компиляции - например, Методы target-C разрешаются поздно и динамически по сравнению с C ++. Java делает большую часть связывания во время загрузки класса: позже, чем C, но раньше, чем Python.

моя любимая цитата из компьютерного противоречия Стэна Келли-Бутла :

время привязки n. Момент, когда хеш-таблица становится поврежденной.

==> Достижения в области вычислительной техники можно сопоставить с «поздним связыванием», которое заставляет меня задуматься о моей так называемой карьере в CS: золотое прошлое, серое настоящее и радужное будущее. Это моя версия оптимизма Synge: трава зеленее, кроме как при t = 0. На EDSAC I мои функции (подпрограммы из 5-канальной бумажной ленты) были перфорированы, сращены и связаны примерно за две недели до ввода. Это известно как преждевременное связывание и требует ловкости с помощью эластичных лент. Далее последовал новый вид фортрана: скучные колоды карт, которые не перетасовывали. Затем с Algol и C я наслаждался статическим связыванием (во время компиляции), пока C ++ не принес ошеломляющие радости динамического (во время выполнения) связывания. Мое текущее исследование направлено на то, чтобы отложить привязку до того момента, пока не исполнится. Я называю это связующим звеном последнего времени, как было предсказано в Евангелии от Матфея: «... и все, что Ты связал на земле, будет связано на небесах ...» (Матфея 16:19 KJV).

...