Чому не існує компілятора python для рідного машинного коду?


25

Як я розумію, причина різниці швидкостей між компільованими мовами та python полягає в тому, що перший компілює код до кінця до коду рідної машини, тоді як python - у байт-коді python для інтерпретації PVM. Я бачу, що таким чином коди python можна використовувати в декількох операційних системах (принаймні в більшості випадків), проте я не розумію, чому не існує додаткового (і необов'язкового) компілятора для python, який компілює так само, як традиційні компілятори . Це дозволить програмісту вибрати, що для них важливіше; багатоплатформованість виконання або продуктивність на рідній машині. Загалом; чому не існує мов, які могли б поводитись як складеними та інтерпретованими?


4
Там є . Haskell також може вести себе як складений або інтерпретований через GHCI
toasted_flakes

У C ++ також є перекладачі . І, ймовірно, тонни інших мов мають обидві реалізації.
Клаудіо

2
Власне, вибираючи IronPythong ( ironpython.net ) та компілюючи створений код ІЛ, використовуючи "ngen" ( msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx ) є спосіб для компіляції Python до рідного машинного коду. Не те, щоб я перевірив цей ланцюжок інструментів.
Док Браун

10
Можна писати компілятори Python до рідних. Вони просто не дуже цікаві, оскільки фактично не покращують продуктивність за будь-яких значних запасів, якщо тільки вони реально не реалізують мову, схожу на Python, але значно обмеженішу. Я раніше десь пояснював десь чому.

Відповіді:


29

Ні. Причина, по якій існують різниці в швидкості між мовами, такими як Python і C ++, полягає в тому, що мови, що мають статичний тип, дають компілятору тони інформації про структуру програми та її дані, що дозволяє оптимізувати як обчислення, так і доступ до пам'яті. Оскільки C ++ знає, що змінна має тип int, вона може визначити оптимальний спосіб управління цією змінною ще до запуску програми. У Python, з іншого боку, час виконання не знає, яке значення має змінну праворуч, поки інтерпретатор не досягне рядка. Це надзвичайно важливо для структур, де в C ++ компілятор може легко визначити розмір структури та кожне розташування її полів у пам'яті під час компіляції. Це дає йому величезну силу для прогнозування способів використання даних і дозволяє оптимізувати їх відповідно до цих прогнозів.

Щоб ефективно компілювати такі мови, як Python, вам потрібно:

  1. Переконайтесь, що структура даних статична під час виконання програми. Це проблематично, оскільки Python має eval та метакласи. Обидва дозволяють змінити структуру програми на основі вхідних даних програми. Це одна з речей, які надають Python такі виразні сили.
  2. Визначте типи всіх змінних, структур та класів із самого вихідного коду. Хоча це можливо до певної міри, система та алгоритм статичного типу були б настільки складними, що їх було б практично неможливо реалізувати корисним способом. Ви можете зробити це для підмножини мови, але точно не для всього набору мовних особливостей.

6
Варто зазначити, що це робить проблему важкою , але не неможливою. sbcl компілює звичайний Lisp, який також є динамічним, має evalі купу інших речей, щоб зробити сумних авторів-компіляторів. Це не до рівня gcc, але це, звичайно, швидше, ніж інтерпретатор CPython.
Даніель Гратцер

3
@jozefg Я сказав, що ефективно компілювати. Не просто компілювати. У Python також є компілятор Cython, який створює нативний код. Справа в тому, що компілятори не зможуть зробити навіть частину оптимізацій, яку можуть компілятори для мов, які мають статичний тип. І коли ви порівнюєте продуктивність, порівнюйте її з компільованим C ++ та не інтерпретованим Python.
Ейфорій

2
Ну насправді ви здивуєтеся, що може зробити sbcl. Гра з орієнтирами показує, що вона працює так само швидко, як Java, майже так само швидко, як і GHC, і в межах від 1 до 10x C. Це не повільно за будь-якими стандартами. Так, динамічні типи певною мірою стримують компіляцію, але не настільки, як вам здається.
Даніель Гратцер

3
Порівнювати швидкість інтерпретованого пітона з компільованим пітоном саме по собі цікаво. Перестаньте говорити "використовувати C ++". Можливо, у вас вже є код, написаний на Python. Можливо, код простіше написати в python. Кому все одно. Що мені важливо, це швидкість у 1,5 рази (що б це не було). Це може зробити величезну зміну.
Томас Едінг

3
Іншими словами, якщо ви хочете компілювати, виберіть іншу мову, яка налаштована на це, наприклад C ++ або Pascal.
Будь ласка_Dont_Bully_Me_SO_Lords

0

Два поняття можуть допомогти нам краще зрозуміти, чому компільований Python на кодовому машинному коді не може працювати так швидко, як компільований C або інші загальнозбірні мови. Їх називають ранньою зв'язкою та пізньою зв'язкою.

Слід почати з того, що я не експерт Python, і я прийшов на цей сайт випадково. Але мені подобається цей сайт.

Як було сказано в іншій відповіді тут, компілятор C ++ може знати багато про програму та приймати рішення щодо того, які операції використовувати для конкретних структур даних. Як приклад, якщо дві цілі змінні потрібно додати разом, компілятор знає, що вони є власними цілими числами, наприклад, 32 біти шириною, і він може додати їх разом з однією інструкцією "ADD". Таким чином, вона компілює інструкцію ADD у код. Він заблокований і не може бути змінений під час роботи програми. Це рання обов'язковість.

З іншого боку, на такій мові, як Python, ми могли б очікувати, що програма поєднує різні типи даних разом складними способами. Тепер компілятор не знає, чи наші 2 змінні - цілі числа, плавці, рядки чи списки. Таким чином, він повинен скласти код, який визначає цю інформацію під час виконання, та вибрати правильну операцію під час роботи програми. Це є пізнім прив'язкою, і ми можемо зрозуміти, що під час роботи програми буде досягнуто додаткової роботи. Це ціна, яку ви платите за збереження цих параметрів відкритими на такій мові, як Python, але це забезпечує максимальну гнучкість роботи.


-4

Я думаю, що це має більше спільного з самою специфікою Python, з тієї ж причини, що ви не можете скласти C # до машинного коду. Мовна специфіка фактично зробить ваші програми помилковими, навіть якщо це можливо через характер мови. Чому б просто не вивчити мову С? Це набагато простіше, ніж C ++ і трохи вдосконалений, ніж Python, але все ж доступний.


5
C # може перейти безпосередньо до машинного коду: Загальний проміжний мова: Попередня компіляція часу - "середовища, сумісні з виконанням CLI, також поставляються з можливістю зробити попередню компіляцію (AOT) збірки, щоб зробити її швидше виконувати шляхом видалення процес JIT під час виконання. У .NET Framework є спеціальний інструмент під назвою Native Image Generator (NGEN), який виконує AOT. У Mono також є можливість зробити AOT. "
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.