なぜPythonスクリプトをコンパイルするのですか? .pyファイルから直接実行でき、正常に動作しますが、パフォーマンス上の利点などはありますか?
また、アプリケーション内の一部のファイルが.pycにコンパイルされ、他のファイルはコンパイルされないことに気付きました。これはなぜですか?
バイトコードにコンパイルされており、はるかに高速に使用できます。
一部のファイルがコンパイルされない理由は、python main.py
で呼び出すメインスクリプトが、スクリプトを実行するたびに再コンパイルされるためです。インポートされたスクリプトはすべてコンパイルされ、ディスクに保存されます。
Ben Blank :による重要な追加
コンパイルされたスクリプトを実行している間、startupの時間が速い(コンパイルする必要がないため)ことはありませんrunより高速です。
.pycファイルはPythonで、既にバイトコードにコンパイルされています。 Pythonは、呼び出した.pyファイルと同じ名前のファイルを見つけると、.pycファイルを自動的に実行します。
「Pythonの概要」 says コンパイルされたPythonファイルについて:
プログラムは、「。py」ファイルから読み取られた場合よりも、「。pyc」または「.pyo」ファイルから読み取られた場合の方が速く実行されません。 「.pyc」または「.pyo」ファイルの方が速いのは、それらがロードされる速度だけです。
.pycファイルを実行する利点は、Pythonを実行する前にコンパイルするオーバーヘッドを負う必要がないことです。とにかく.pyファイルを実行する前にPythonがバイトコードにコンパイルされるため、それ以外のパフォーマンスの改善はありません。
コンパイル済みの.pycファイルを使用すると、どの程度改善できますか?それはスクリプトが何をするかに依存します。 「Hello World」を単に出力する非常に短いスクリプトの場合、コンパイルが起動と実行の合計時間の大部分を占める可能性があります。しかし、実行時間の合計に対するスクリプトのコンパイルのコストは、実行時間の長いスクリプトでは減少します。
コマンドラインで指定したスクリプトは、決して.pycファイルに保存されません。その「メイン」スクリプトによってロードされたモジュールのみがその方法で保存されます。
プラス:
最初:軽度の、無効化可能な難読化。
2番目:コンパイルの結果、ファイルが大幅に小さくなる場合、ロード時間が短縮されます。 Webに最適です。
3番目:Pythonはコンパイル手順をスキップできます。初期ロードで高速。 CPUとWebに最適です。
4番目:コメントするほど、ソース.pyc
ファイルと比較して.pyo
または.py
ファイルが小さくなります。
5番目:.pyc
または.pyo
ファイルのみを手に持っているエンドユーザーは、元に戻すのを忘れてしまった、元に戻せない変更に起因するバグを提示する可能性ははるかに低くなります。
6番目:組み込みシステムを目指している場合、より小さいサイズのファイルを取得することは大きなプラスになり、アーキテクチャは安定しているため、以下で説明する欠点1は役に立たない。
トップレベルのコンパイル
最上位のpythonソースファイルを.pyc
ファイルに次のようにコンパイルできることを知っておくと便利です。
python -m py_compile myscript.py
これにより、コメントが削除されます。 docstrings
はそのまま残ります。 docstrings
も削除したい場合(その理由を真剣に考えたいかもしれません)、代わりにこの方法でコンパイルしてください...
python -OO -m py_compile myscript.py
...そして、.pyo
ファイルの代わりに.pyc
ファイルを取得します;コードの本質的な機能に関しては同様に配布可能ですが、削除されたdocstrings
のサイズだけ小さくなります(最初の段階でまともなdocstrings
があった場合、その後の雇用では理解しにくくなります)。ただし、以下の欠点3を参照してください。
pythonは、.py
ファイルの日付を使用して、.py
または.pyc
ファイルではなく、.pyo
ファイルを実行するかどうかを決定することに注意してください--- .pyファイルと.pyc
を編集しますまたは.pyo
は廃止され、得られたメリットはすべて失われます。 .pyc
または.pyo
の利点を再び取得するには、再コンパイルする必要があります。
欠点:
最初:.pyc
および.pyo
ファイルには、pythonファイルがコンパイルされたシステムアーキテクチャを示す「マジックCookie」があります。これらのファイルの1つを異なるタイプの環境に配布すると、破損します。 .pyc
または.pyo
を再コンパイルする.py
またはtouch
なしで配布すると、.pyc
または.pyo
が優先されるため、エンドユーザーも修正できません。
2番目:上記の-OO
コマンドラインオプションを使用してdocstrings
をスキップした場合、誰もその情報にアクセスできず、コードの利用がより困難(または不可能)になります。
3番目:Pythonの-OO
オプションは、-O
コマンドラインオプションに従っていくつかの最適化も実装します。これにより、動作が変更される場合があります。既知の最適化は次のとおりです。
sys.flags.optimize
= 1assert
ステートメントはスキップされます__debug__
= False4番目:最初の行に#!/usr/bin/python
のオーダーでpythonスクリプトを意図的に実行可能にした場合、これは.pyc
および.pyo
ファイルで削除され、その機能は失われます。
5番目:やや明らかですが、コードをコンパイルすると、その使用に影響が及ぶだけでなく、他の人があなたの作業から学ぶ可能性が大幅に低下します。
コンパイル済みpythonの実行でパフォーマンスが向上します。ただし、インポートしたモジュールとして.pyファイルを実行すると、pythonはそれをコンパイルして保存し、.pyファイルが変更されない限り、常にコンパイルされたバージョンを使用します。
ファイルが使用される場合、インターペッティングされた言語では、プロセスは次のようになります。
1。ファイルはinterpeterによって処理されます。
2。ファイルがコンパイルされます
3。コンパイルされたコードが実行されます。
明らかに、プリコンパイルされたコードを使用することにより、ステップ2を削除できます。これは、python、PHPなどに適用されます。
違いを説明する興味深いブログ投稿があります http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html
そして、ここにPythonコンパイルプロセスを説明するエントリがあります http://effbot.org/zone/python-compile.htm
既に述べたように、pythonコードをバイトコードにコンパイルすることでパフォーマンスを向上させることができます。これは通常、インポートされたスクリプトに対してのみ、python自体によって処理されます。
pythonコードをコンパイルするもう1つの理由は、知的財産がコピーおよび/または変更されるのを防ぐためです。
詳細については、 Pythonドキュメント をご覧ください。
コンパイルされたスクリプトを実行すると、確かにパフォーマンスの違いがあります。通常の.py
スクリプトを実行すると、マシンは実行されるたびにコンパイルし、時間がかかります。最近のマシンでは、これはほとんど目立ちませんが、スクリプトが大きくなるにつれて、問題になる可能性があります。
触れられていないものは source-to-source-compiling です。たとえば、nuitka
はPythonコードをC/C++に変換し、低速の仮想マシンで実行されるPythonバイトコードではなく、CPUで直接実行されるバイナリコードにコンパイルします。
これは大幅な高速化につながる可能性があります。または、環境がC/C++コードに依存しているときにPythonで作業できるようになります。
コンパイルされたコードを使用して、ソースコードにアクセスできないユーザーに配布します。基本的に、経験の浅いプログラマが誤って何かを変更したり、バグを修正したりするのを止めるためです。
はい、パフォーマンスが主な理由であり、私が知る限り、唯一の理由です。
一部のファイルがコンパイルされていない場合、おそらくディレクトリのアクセス権などが原因で、Pythonが.pycファイルに書き込めない可能性があります。または、おそらくコンパイルされていないファイルはロードされません...(スクリプト/モジュールは、最初にロードされたときにのみコンパイルされます)
初心者は、Pythonが.pycファイルのためにコンパイルされていると想定しています。 .pycファイルはコンパイルされたバイトコードであり、これが解釈されます。そのため、以前にPythonコードを実行し、.pycファイルを手元に置いた場合、バイトコードを再コンパイルする必要がないため、2回目の実行が高速になります。
compiler:コンパイラは、高水準言語を機械語に翻訳するコードです
インタープリター:インタープリターは、高レベル言語を機械で読み取り可能な同等のバイナリに変換します。インタープリターは、実行する高レベル言語コードを取得するたびに、コードを中間コードに変換してからマシンコードに変換します。コードの各部分が解釈され、シーケンスで個別に実行され、コードの一部でエラーが検出されると、次のコードセットを変換せずにコードの解釈が停止します。
出典:http://www.toptal.com/python/why-are-there-so-many-pythonshttp://www.engineersgarage.com/contribution/difference-between-compiler-and-interpreter