Почему нет компилятора Python для машинного кода?

25

Как я понимаю, причина разницы в скорости между скомпилированными языками и python заключается в том, что первый компилирует код вплоть до кода нативной машины, тогда как python компилирует в байт-код python для интерпретации PVM. Я вижу, что таким образом коды Python могут использоваться в нескольких операционных системах (по крайней мере, в большинстве случаев), однако я не понимаю, почему нет дополнительного (и необязательного) компилятора для Python, который компилируется так же, как и традиционные компиляторы , Это оставит программисту выбирать, что для них важнее; многоплатформенная исполняемость или производительность на родной машине. В целом; почему нет языков, которые можно было бы вести как скомпилированными, так и интерпретированными?

user2986898
источник
4
Там является . Haskell также может вести себя как скомпилированный или интерпретированный через GHCI
toasted_flakes
C ++ также имеют переводчиков . И, вероятно, тонны других языков имеют обе реализации.
Клаудио
2
На самом деле, выбирая IronPythong ( ironpython.net ) и обобщать полученный код IL с помощью «NGEN» ( msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx ) есть это способ скомпилировать Python для машинного кода. Не то чтобы я тестировал эту цепочку инструментов.
Док Браун
10
Можно написать Python-to-native компиляторы. Они просто не очень интересны, потому что они на самом деле не улучшают производительность каким-либо существенным преимуществом, если только они на самом деле не реализуют язык, похожий на Python, но гораздо более ограниченный. Я ранее объяснил, почему в другом месте .

Ответы:

29

Нет. Причина, по которой существуют различия в скорости между такими языками, как Python и C ++, заключается в том, что статически типизированные языки дают компилятору тонны информации о структуре программы и ее данных, что позволяет оптимизировать как вычисления, так и доступ к памяти. Поскольку C ++ знает, что переменная имеет тип int, она может определить оптимальный способ манипулирования этой переменной даже до запуска программы. В Python, с другой стороны, среда выполнения не знает, какое значение находится в переменной, пока интерпретатор не достигнет строки. Это чрезвычайно важно для структур, где в C ++ компилятор может легко определить размер структуры и каждое расположение ее полей в памяти во время компиляции. Это дает ему огромные возможности в прогнозировании использования данных и позволяет оптимизировать их в соответствии с этими прогнозами.

Для эффективной компиляции таких языков, как Python, вам необходимо:

  1. Убедитесь, что структура данных является статической во время выполнения программы. Это проблематично, потому что в Python есть eval и метаклассы. И то, и другое позволяет изменить структуру программы на основе ввода программы. Это одна из вещей, которые дают Python такую ​​выразительную силу.
  2. Выведите типы всех переменных, структур и классов из самого исходного кода. Хотя это возможно до некоторой степени, система и алгоритм статического типа будут настолько сложными, что их будет практически невозможно реализовать удобным для использования способом. Вы можете сделать это для подмножества языка, но определенно не для всего набора языковых возможностей.
Euphoric
источник
6
Стоит отметить, что это делает проблему сложной , но не невозможной. sbcl компилирует Common Lisp, который также является динамическим, имеет evalи кучу других вещей, которые расстраивают авторов компиляторов. Это не до уровня gcc, но, безусловно, быстрее, чем интерпретатор CPython.
Даниэль Гратцер
3
@jozefg Я сказал, эффективно компилировать. Не просто компилировать. В Python также есть компилятор Cython, который создает собственный код. Дело в том, что эти компиляторы не могут выполнить даже часть оптимизаций, которые могут выполнять компиляторы для языков со статической типизацией. А когда вы сравниваете производительность, сравнивайте ее с скомпилированным C ++ и не интерпретируемым Python.
Эйфорическая
2
Ну, на самом деле, вы будете удивлены тем, что может сделать sbcl. Тестовая игра показывает, что она работает так же быстро, как Java, почти так же быстро, как GHC, и в пределах от 1x до 10x C. Она не медленная ни по каким стандартам. Да, динамические типы в некоторой степени тормозят компиляцию, но не так сильно, как кажется.
Даниэль Гратцер
3
Сравнение скорости интерпретируемого питона с компилированным питоном само по себе интересно. Перестаньте говорить "используйте C ++". Возможно, у вас уже есть код, написанный на Python. Возможно, код легче написать на python. Какая разница. Что меня волнует, так это увеличение скорости в 1,5 раза (что бы это ни было). Это может иметь огромное значение.
Томас Эдинг
3
Другими словами, если вы хотите скомпилировать, выберите другой язык, который настроен для этого, например C ++ или Pascal.
Please_Dont_Bully_Me_SO_Lords
0

Две концепции могут помочь нам лучше понять, почему Python, скомпилированный с собственным машинным кодом, «может» работать не так быстро, как скомпилированный C или другие обычно скомпилированные языки. Их называют ранним связыванием и поздним связыванием.

Я должен начать с того, что я не эксперт по Python, и я попал на этот сайт случайно. Но мне нравится этот сайт.

Как уже упоминалось в другом ответе, компилятор C ++ может много знать о программе и принимать решения о том, какие операции использовать для конкретных структур данных. Например, если две целочисленные переменные необходимо сложить вместе, компилятор знает, что они являются родными целыми числами, например, 32-битной шириной, и он может добавить их вместе с помощью одной инструкции "ADD". Таким образом, он компилирует инструкцию ADD в код. Он заблокирован и не может быть изменен во время работы программы. Это раннее связывание.

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

user214354
источник
-4

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

кусачий
источник
5
C # может переходить непосредственно к машинному коду: Common Intermediate Language: Компиляция с опережением времени - «CLI-совместимые среды выполнения также поставляются с возможностью выполнять компиляцию с опережением времени (AOT) сборки, чтобы ускорить ее выполнение путем удаления процесс JIT во время выполнения. В .NET Framework есть специальный инструмент, называемый Native Image Generator (NGEN), который выполняет AOT. В Mono также есть возможность сделать AOT. "