Навіщо компілювати Python-код?


241

Навіщо ви складати сценарій Python? Ви можете запустити їх безпосередньо з файлу .py, і він працює чудово, тож чи є перевага в продуктивності чи щось таке?

Я також помічаю, що деякі файли в моїй програмі збираються в .pyc, а інші - чому це так?


Ви також можете відзначити, що, включаючи швидший запуск програми, ви також отримуєте безпеку, якщо не можете поділитися своїм кодом, якщо це корпоративна таємниця.
Please_Dont_Bully_Me_SO_Lords

@PSyLoCKe Ти справді, насправді не так. Байт-код Python справді читабельний, тому що компілятору не потрібно його придушувати, щоб оптимізувати його. (Не те що це дуже оптимізує ...)
wizzwizz4

1
Причина, що деякі файли збираються автоматично, полягає в тому, що вони імпортуються; Наприклад, якщо ви використовуєте import mylib.py, Python буде компілюватися, mylib.pyщоб майбутні importоперації запускалися трохи швидше. Якщо ви пізніше зміните mylib.py, то він буде перекомпільований наступного разу, коли він імпортується (Python використовує дату файлу, щоб побачити, що це відбувається.)
fyngyrz

Відповіді:


270

Він компілюється в байт-код, який можна використовувати набагато, набагато, набагато швидше.

Причина, що деякі файли не компілюються, полягає в тому, що основний скрипт, до якого ви посилаєтесь python main.py, перекомпілюється щоразу, коли ви запускаєте сценарій. Всі імпортовані сценарії будуть складені та збережені на диску.

Важливе доповнення Бен Бланк :

Варто зауважити, що при виконанні компільованого сценарію швидший час запуску (оскільки його не потрібно компілювати), він не працює швидше.


260
Варто зауважити, що при виконанні компільованого сценарію швидший час запуску (оскільки його не потрібно компілювати), він не працює швидше.
Бен Бланк

24
Поширене оману. Дякую, що поділились.
матюк

1
Окрім того, що не потребує компіляції, .pyc-файл майже незмінно менший. Особливо, якщо ви багато коментуєте. Один мій - 28419 як .py, але лише 17879 як .pyc - значить, і час завантаження також кращий. Нарешті, ви можете попередньо
скласти

1
Чи є різниця у споживанні пам'яті? Я тестую Python на вбудованих пристроях на базі mips cpu з лише 64 Мб оперативної пам’яті, тож чи є якась перевага у використанні пам’яті при запуску компільованої версії сценарію python?
валент

1
@valentt: Напевно, ні. Я не знаю багато про внутрішню програму Python, але не думаю, що аналіз на байт-код забирає багато пам’яті в Python. Я не можу придумати щось, що потребує багато пам’яті, щоб запам'ятати якийсь стан.
Георг Шоллі

80

Файл .pyc - це Python, який вже був складений у байт-код. Python автоматично запускає файл .pyc, якщо він знайде файл з тим самим іменем, що і файл .py, до якого ви викликаєте.

"Вступ до Python" говорить про це для складених файлів Python:

Програма не запускається швидше, коли вона читається з файлу '.pyc' або '.pyo', ніж коли вона читається з файлу '.py'; єдине, що швидше стосується файлів '.pyc' або '.pyo', - це швидкість, з якою вони завантажуються.

Перевага запуску файлу .pyc полягає в тому, що Python не повинен виконувати накладні витрати на його компіляцію перед його запуском. Оскільки Python буде компілюватись до байт-коду, перш ніж запустити файл .py, все одно, окрім цього, не повинно бути покращено продуктивність.

Скільки поліпшень можна отримати за допомогою компільованих файлів .pyc? Це залежить від того, що робить сценарій. Для дуже короткого сценарію, який просто друкує "Hello World", компіляція може становити великий відсоток від загального часу запуску та запуску. Але вартість компіляції сценарію відносно загального часу виконання зменшується для більш тривалих сценаріїв.

Сценарій, який ви називаєте в командному рядку, ніколи не зберігається у файл .pyc. Таким чином зберігаються лише модулі, завантажені цим "головним" сценарієм.


3
У багатьох випадках різко помітити різницю, але у мене є певний файл python з більш ніж 300 000 рядків. (Це купа математичних обчислень, згенерованих іншим сценарієм для тестування) На збирання потрібно 37 секунд, а на виконання - лише 2 секунди.
wojtow

54

Плюси:

По-перше: легке, поразкове затьмарення.

По-друге: якщо компіляція призведе до значно меншого файлу, ви отримаєте швидший час завантаження. Приємно для Інтернету.

Третє: Python може пропустити етап компіляції. Швидше при ініціальному навантаженні. Приємно для процесора та Інтернету.

По-четверте: чим більше ви коментуєте, тим меншим буде .pycабо .pyoфайл порівняно з вихідним .pyфайлом.

По-п’яте: кінцевий користувач, у якому є лише файл .pycабо .pyoфайл, набагато рідше подасть вам помилку, яку вони викликали неповернені зміни, про які вони забули розповісти.

По-шосте: якщо ви орієнтуєтесь на вбудовану систему, отримання файлу меншого розміру для вбудовування може бути значним плюсом, а архітектура стабільна, тому недолік, деталізований нижче, не вживається.

Компіляція верхнього рівня

Корисно знати, що ви можете зібрати вихідний файл пітона верхнього рівня у .pycфайл таким чином:

python -m py_compile myscript.py

Це видаляє коментарі. Він залишає docstringsнедоторканим. Якщо ви також хочете позбутися цього docstrings(ви можете серйозно задуматися над тим, для чого це робите), тоді замість цього складіть цей ...

python -OO -m py_compile myscript.py

... і ви отримаєте .pyoфайл замість .pycфайлу; однаково розповсюджується з точки зору основної функціональності коду, але менший за розміром викресленого docstrings(і менш легко зрозумілий для подальшого працевлаштування, якщо він docstringsв першу чергу був гідним ). Але дивіться недолік три нижче.

Зауважте, що python використовує .pyдату файлу, якщо вона присутня, щоб вирішити, чи слід виконувати .pyфайл на відміну від .pycабо .pyoфайл ---, тож відредагуйте файл .py, .pycабо .pyoвін застарілий, і всі отримані вами переваги втрачаються. Вам необхідно перебудувати його для того , щоб отримати .pycабо .pyoвигоди знову назад, наприклад, вони можуть бути.

Недоліки:

По-перше: є "магічне файли cookie" .pycта .pyoфайли, які вказують на системну архітектуру, в яку був складений файл python. Якщо ви поширите один з цих файлів у середовищі іншого типу, він порушиться. Якщо ви поширюєте .pycабо .pyoбез пов’язаного .pyз ним перекомпіляції або touchтаким чином він замінює .pycабо .pyo, кінцевий користувач також не може його виправити.

По-друге: Якщо docstringsбуде пропущено використання параметра -OOкомандного рядка, як описано вище, ніхто не зможе отримати цю інформацію, яка може ускладнити (або неможливо) використання коду.

По-третє: -OOопція Python також здійснює деякі оптимізації відповідно до -Oпараметра командного рядка; це може призвести до змін в роботі. Відомими оптимізаціями є:

  • sys.flags.optimize = 1
  • assert заяви пропускаються
  • __debug__ = Неправдивий

В- четверте , якщо ви навмисно зробили свій пітон скрипт виконуваним з чим - то порядку #!/usr/bin/pythonна першій лінії, це роздягли в .pycі .pyoфайлів і функціональність втрачається.

По-п’яте: дещо очевидно, але якщо ви скомпонуєте свій код, на його використання може вплинути не тільки його використання, але й потенціал, щоб інші навчились вашій роботі, скорочується, часто сильно.


10

Спостерігається збільшення продуктивності запущеного компільованого пітона. Однак, коли ви запускаєте .py-файл як імпортний модуль, python буде компілювати та зберігати його, і поки файл .py не зміниться, він завжди використовуватиме компільовану версію.

З будь-якою інтерпретованою мовою, коли використовується файл, процес виглядає приблизно так:
1. Файл обробляється інтерпетером.
2. Складається файл
3. Скомпільований код виконується.

очевидно, використовуючи попередньо складений код, ви можете усунути крок 2, це стосується python, PHP та інших.

Ось цікава публікація в блозі, що пояснює відмінності http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html
А ось запис, який пояснює процес компіляції Python http://effbot.org/zone /python-compile.htm


9

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

Іншою причиною, з якою ви хочете скласти свій пітон-код, може бути захист вашої інтелектуальної власності від копіювання та / або модифікації.

Детальніше про це ви можете прочитати в документації на Python .


2
Що стосується захисту вашого коду - компіляція не допоможе багато. Компіляція обфускатів - але хтось із бажанням отримає ваш код незалежно.
Джош Смітон

1
@josh, що завжди можливо, якщо ви можете отримати доступ до пам'яті або переглядати інструкції на процесор, достатньо часу і зможуть вони переробити ваш додаток.
UnkwnTech

5
Однак, як сказав Unkwntech, погодилися, що це завжди буде можливо, якщо людина достатньо рішуча. Але я переконаний, що цього буде досить у більшості ситуацій, коли ти просто хочеш обмежити людей "фіксувати" свій код ...
Саймон Б. Дженсен

Мови, які компілюються в байт - код , як правило , не всі , що важко реверс-компіляції , якщо не вжити додаткових заходів , щоб заплутати їх - просто компіляції , як правило , не буде достатньо.
EJoshuaS

7

Звичайно, є різниця в продуктивності під час запуску компільованого сценарію. Якщо ви запускаєте звичайні .pyсценарії, машина збирає їх кожен раз, коли він запускається, і це потребує часу. На сучасних машинах це навряд чи помітно, але в міру зростання сценарію це може стати більшою проблемою.


7

Щось, що не торкнулося, - це компіляція від джерела до джерела . Наприклад, nuitkaперекладає код Python на C / C ++ і компілює його у двійковий код, який безпосередньо працює на процесорі, а не байт-код Python, який працює на повільній віртуальній машині.

Це може призвести до значних прискорень, або це дозволить вам працювати з Python, поки ваше середовище залежить від коду C / C ++.


4

Ми використовуємо компільований код для розповсюдження серед користувачів, які не мають доступу до вихідного коду. В основному, щоб зупинити недосвідчених програмістів, щоб випадково щось змінити чи виправити помилки, не повідомивши нам.


2

Так, ефективність - це головна причина і, наскільки я знаю, єдина причина.

Якщо деякі ваші файли не збираються, можливо, Python не в змозі записати у файл .pyc, можливо, через дозволи до каталогу чи щось. Або, можливо, некомпільовані файли просто ніколи не завантажуються ... (сценарії / модулі збираються лише при першому завантаженні)


1

Початківці припускають, що Python складено через файли .pyc. Файл .pyc - це компільований байт-код, який потім інтерпретується. Тож якщо ви раніше запустили свій Python-код і матимете .pyc-файл під рукою, він запуститься швидше вдруге, оскільки не потрібно повторно компілювати байт-код

компілятор: компілятор - це фрагмент коду, який переводить мову високого рівня в машинну мову

Інтерпретатори: Інтерпретатори також перетворюють мову високого рівня в машиночитані бінарні еквіваленти. Кожен раз, коли перекладач отримує код мови високого рівня для виконання, він перетворює код у проміжний код, перш ніж перетворювати його в машинний код. Кожна частина коду інтерпретується, а потім виконується окремо в послідовності, а в частині коду виявлена ​​помилка, вона зупинить інтерпретацію коду без перекладу наступного набору кодів.

Джерела: http://www.toptal.com/python/why-are-there-so-many-pythons http://www.engineersgarage.com/contribution/difference-between-compiler-and-interpreter


9
Ваше визначення "компілятора" невірно. Компілятор ніколи не піддавався компіляції до машинного коду. Компілятор - це лише перекладач з однієї мови на іншу. Ось чому ми говоримо, що Python "компілює" для байт-коду, Coffeescript "компілює" в Javascript і так далі і так далі.
Ріккі Стюарт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.