Python интерпретируется или компилируется?

76

Это просто удивление, которое я испытал, читая о интерпретируемых и компилируемых языках.

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

Теперь перейдем к Python :

  • Код Python ( somefile.py ) при импорте создает файл ( somefile.pyc ) в том же каталоге. Допустим, импорт выполняется в оболочке Python или модуле Django. После импорта я немного изменяю код и снова выполняю импортированные функции, чтобы обнаружить, что он все еще выполняет старый код. Это говорит о том, что файлы * .pyc представляют собой скомпилированные файлы Python, аналогичные исполняемым файлам, созданным после компиляции файла C, хотя я не могу выполнить файл * .pyc напрямую.
  • Когда файл python (somefile.py) выполняется напрямую (./somefile.py или python somefile.py), файл .pyc не создается, а код выполняется так, как указывает на интерпретированное поведение.

Они предполагают, что код python компилируется каждый раз, когда он импортируется в новый процесс для создания .pyc, в то время как он интерпретируется при непосредственном выполнении.

Так какой тип языка мне следует рассматривать? Интерпретируется или компилируется? И как его эффективность сравнивается с интерпретируемыми и скомпилированными языками?

Согласно странице вики в переводе с языков , он указан как язык, скомпилированный с кодом виртуальной машины. Что это значит?

crodjer
источник
1
Когда возникают сомнения относительно того, является ли Ruby интерпретируемым языком? Когда это скомпилировано. :) macruby.org
mipadi
8
Стоит отметить, что ни один современный язык не интерпретируется в строгом смысле. Практически все они компилируются в байт-код.
Уинстон Эверт
@ Уинстон Эверт: браво! Applesoft Basic (в 1980-х) был скомпилирован байт-код. «современный» в данном случае означает каждый интерпретируемый язык в живой памяти, с единственным возможным исключением, являющимся некоторыми элементарными реализациями Dartmouth Basic.
S.Lott
6
>> Напротив, C - это скомпилированный язык << root.cern.ch/drupal/content/cint
igouy
3
@ S.Lott: Вызывать процесс токенизации, который интерпретаторы Applesoft и BASIC 80-х сделали «компиляцией байт-кода», более чем неискренне. Да, код программы, введенный пользователем, был сохранен в памяти в сжатом виде, один байт на зарезервированное слово, но ничего не было сделано до тех пор, пока вы не набрали текст RUN. Это было, как если бы у вас был компилятор, который выполнил шаг лексирования, а затем вывел поток токенов, которые нужно было повторно анализировать при каждом запуске программы. Совсем не похоже на современную компиляцию байт-кода, как это делается, скажем javac, с использованием лексирования, анализа и оптимизации.
dodgethesteamroller

Ответы:

80

Стоит отметить, что языки не интерпретируются и не компилируются, а, скорее, реализации языка либо интерпретируют, либо компилируют код. Вы отметили, что Ruby - это «интерпретируемый язык», но вы можете скомпилировать Ruby в стиле MacRuby , так что это не всегда интерпретируемый язык.

Практически каждая реализация Python состоит из интерпретатора (а не компилятора). Эти .pycфайлы вы видите байт - код для виртуальной машины Python ( по аналогии с Явы .classфайлов). Они не совпадают с машинным кодом, сгенерированным компилятором C для собственной машинной архитектуры. Тем не менее, некоторые реализации Python состоят из компилятора, который работает точно по времени , который скомпилирует байт-код Python в машинный код.

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

mipadi
источник
В зависимости от вашего определения, существуют машинные компиляторы для Python. Некоторые компилируют только подмножество python. Другие реализуют весь python, но используют python API для фактического выполнения операций, которые он не может выполнить в C.
Winston Ewert
Я думаю, вы на самом деле описываете, что Python - это то, что я бы назвал «полукомпилированным», или он может быть полностью скомпилированным. Под полускомпилированным я подразумеваю, что поскольку он обычно компилируется в файл .pyc «промежуточного языка», который используется виртуальной машиной Python, он обычно запускается из этой «полускомпилированной» формы, что обычно делает код быстрее, чем простая интерпретация интерпретируемого кода во время выполнения. Интересно, что полускомпилированный код иногда может быть быстрее, чем нативно скомпилированный код (например, C # обычно быстрее, чем C ++).
Крис Хэлкроу
5
Cython компилирует код Python в C, чтобы его можно было скомпилировать как общий объект.
Greyfade
Различение байт-кода и машинного кода таким образом довольно произвольно. Java компилируется: компилятор javac создает файлы классов, содержащие инструкции низкого уровня, которые могут быть выполнены либо на виртуальной машине (например, в точке доступа), либо напрямую аппаратно (например, на процессорах ARM с расширением Jazelle). Насколько я знаю, нет технической причины, по которой подобная архитектура процессора не могла бы быть разработана для непосредственного выполнения команд python vm.
Жюль
@Jules По совпадению, код Jython фактически скомпилирован в файлы .class, которые, я считаю, используются повторно, пока вы не измените исходный код py.
JimmyJames
35

Python попадет под интерпретируемый байт-код. .pyИсходный код сначала компилируется в байтовый код как .pyc. Этот байт-код может быть интерпретирован (официальный CPython) или скомпилирован JIT (PyPy). Исходный код Python ( .py) может быть скомпилирован с другим байтовым кодом, например, IronPython (.Net) или Jython (JVM). Существует несколько реализаций языка Python. Официальный - интерпретируемый байт-код. Существуют также скомпилированные JIT-реализации байт-кода.

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

aufather
источник
Спасибо за информацию. Согласно тестам, производительность Python значительно снизилась!
crodjer
1
Ссылка, которую я дал очень ясно, утверждает, что это ошибочные тесты языковых реализаций . Python не должен быть вашим выбором языка, если вы слишком беспокоитесь о производительности выполнения. Если вы все еще хотите сравнить, сравните похожие языки. Байт-код, интерпретируемый официальным CPython, сопоставим или быстрее, чем JIT-скомпилированный Ruby.
aufather
1
@ jase21 - «Мои планы на 2006 год состоят в том, чтобы перенести методы, реализованные в Psyco, на PyPy. PyPy позволит нам создать более гибкий специализатор JIT, с которым будет легче экспериментировать, и при этом не придется тратить время на синхронизацию с эволюцией язык Python. " psyco.sourceforge.net/introduction.html
igouy
1
@ jase21 - «заставляет коды Python работать быстрее, чем части C-счетчика» - Должны ли мы просто поверить вам на слово?
igouy
3
Ссылка в ответе не работает.
Basilevs
11

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

Компилятор (в широком смысле) является переводчиком . Программа переводит программу A в программу B и в будущем выполняет ее на машине M.

Переводчик (в широком смысле) является исполнителем . Это машина M, которая выполняет программу A. Хотя мы обычно исключаем из этого определения физические машины (или нефизические машины, которые действуют так же, как физические). Но с теоретической точки зрения это различие несколько произвольно.


Например, взять re.compile. Он «компилирует» регулярное выражение в промежуточную форму, и эта промежуточная форма интерпретируется / оценивается / выполняется.


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

CPython (наиболее популярная реализация языка Python) в основном интересен для выполнения кода. Поэтому CPython обычно описывается как интерпретированный. Хотя это свободный ярлык.

Пол Дрэйпер
источник
7

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

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

Насколько я знаю, Ruby> = 1.9 тоже использует виртуальную машину, такую ​​как Python.

LennyProgrammers
источник
5

Среда выполнения Python запускает пользовательский объектный код (байт-код) на виртуальной машине.

Процесс компиляции преобразует исходный код в объектный код.

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

ykombinator
источник