Зачем компилировать код Python?

241

Зачем вам компилировать скрипт на Python? Вы можете запустить их непосредственно из файла .py, и он работает нормально, так есть ли преимущество в производительности или что-то еще?

Я также заметил, что некоторые файлы в моем приложении компилируются в .pyc, а другие нет, почему это так?

ryeguy
источник
Вы также можете заметить, что, в том числе более быстрый запуск вашего приложения, вы также получаете безопасность, если не можете поделиться своим кодом, если это корпоративный секрет.
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
Распространенное заблуждение. Спасибо, что поделился.
Matpie
1
В дополнение к тому, что не требуется компиляция, файл .pyc почти всегда меньше. Особенно, если вы много комментируете. Один из моих 28419 как .py, но только 17879 как .pyc - так что время загрузки также лучше. Наконец, вы можете прекомпилировать сценарии верхнего уровня следующим образом: python -m compileall myscript.py
fyngyrz
1
Есть ли разница в потреблении памяти? Я тестирую Python на встраиваемых устройствах на базе процессора MIPS с 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 файл имеет гораздо меньше шансов представить вам ошибку, вызванную необратимым изменением, о котором он забыл сообщить вам.

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

Компиляция высшего уровня

Полезно знать, что вы можете скомпилировать исходный файл Python верхнего уровня в .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файлов и функциональность теряется.

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

fyngyrz
источник
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

UnkwnTech
источник
9

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

Другая причина, по которой вы можете захотеть скомпилировать свой код на python, может заключаться в защите вашей интеллектуальной собственности от копирования и / или изменения.

Вы можете прочитать больше об этом в документации по Python .

Саймон Б. Дженсен
источник
2
Что касается защиты вашего кода - компиляция не очень поможет. Компиляция запутывает - но кто-то с желанием получит ваш код независимо.
Джош Смитон
1
@ josh, это всегда возможно, если можно получить доступ к памяти или посмотреть инструкции к процессору, и у них будет достаточно времени, и они смогут заново создать ваше приложение.
UnkwnTech
5
Согласен, однако, как сказал Unkwntech, это всегда будет возможно, если человек будет достаточно решительным. Но я убежден, что этого будет достаточно в большинстве ситуаций, когда вы, как правило, просто хотите ограничить людей от «исправления» вашего кода ...
Саймон Б. Дженсен
Языки, которые компилируются в байт - код , как правило , не все , что трудно реверс-компиляции , если не принять дополнительные меры , чтобы запутать их - просто компиляции , как правило , не будет достаточно.
EJoshuaS - Восстановить Монику
7

Конечно, разница в производительности при запуске скомпилированного скрипта. Если вы запускаете обычные .pyсценарии, машина компилирует их каждый раз, когда это выполняется, и на это требуется время. На современных машинах это едва заметно, но по мере роста сценария это может стать проблемой.

matpie
источник
7

Что-то, что не затронуто, является компиляцией источника к источнику . Например,nuitka переводит код Python на C / C ++ и компилирует его в двоичный код, который непосредственно выполняется на ЦП, вместо байт-кода Python, который выполняется на более медленной виртуальной машине.

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

user258532
источник
4

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

DrBwts
источник
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 и так далее, и так далее.
Рикки Стюарт,