Pythonコードをコンパイルする理由


241

なぜPythonスクリプトをコンパイルするのですか?.pyファイルから直接実行することができ、正常に動作するため、パフォーマンス上の利点はありますか?

また、アプリケーションの一部のファイルが.pycにコンパイルされるのに、他のファイルはコンパイルされないことにも気付きました。なぜですか?


また、アプリケーションの起動が高速であることを含め、コードが企業秘密である場合にコードを共有できないと、セキュリティが向上することにも注意してください。
Please_Dont_Bully_Me_SO_Lords 2018

@PSyLoCKeあなたは本当に、本当にしません。コンパイラーは最適化のために難読化する必要がないため、Pythonバイトコードは本当に読みやすいです。(それはそれを大幅に最適化するというわけではありません...)
wizzwizz4

1
一部のファイルが自動的にコンパイルされる理由は、それらがインポートされるためです。たとえば、を使用するとimport mylib.py、Pythonがコンパイルされるmylib.pyため、将来のimportステートメントの実行が少し速くなります。後で変更する場合はmylib.py、それはそれがインポートされ、再コンパイルされ、次回を取得します(Pythonはこの問題が発生したことを確認するためにファイルの日付を使用しています。)
fyngyrzを

回答:


269

これはバイトコードにコンパイルされており、非常に高速に使用できます。

一部のファイルがコンパイルされない理由python main.pyは、スクリプトを実行するたびに呼び出されるメインスクリプトが再コンパイルされるためです。インポートされたすべてのスクリプトはコンパイルされ、ディスクに保存されます。

Ben Blankによる重要な追加:

コンパイルされたスクリプトを実行すると起動 時間が速くなりますが(コンパイルする必要がないため)、実行速度が速くなることはありません。


259
コンパイルされたスクリプトを実行すると起動時間が速くなりますが(コンパイルする必要がないため)、実行速度が速くなることはありません。
Ben Blank

24
よくある誤解。共有いただきありがとうございます。
マッピー2009年

1
コンパイルが不要なことに加えて、.pycファイルはほぼ常に小さくなります。特にたくさんコメントするなら。私の1つは.pyとして28419ですが、.pycとしては17879です-したがって、ロード時間も優れています。最後に、次の方法でトップレベルのスクリプトをプリコンパイルできます:python -m compileall myscript.py
fyngyrz

1
メモリ消費量に違いはありますか?64MBのRAMのみを搭載したmips cpuに基づく組み込みデバイスでPythonをテストしているので、コンパイルされたバージョンのPythonスクリプトを開始するときにメモリ使用量に利点はありますか?
バレット

1
@valentt:おそらく違います。Pythonの内部についてはよくわかりませんが、バイトコードへの解析にはPythonで大量のメモリが必要になるとは思いません。ある状態を記憶するために多くのメモリを必要とするものは考えられません。
GeorgSchölly2014

80

.pycファイルは、バイトコードにコンパイル済みのPythonです。Pythonは、起動した.pyファイルと同じ名前のファイルが見つかると、自動的に.pycファイルを実行します。

「Python入門」では、コンパイルされたPythonファイルについて次のように述べています。

「.pyc」または「.pyo」ファイルから読み取られたプログラムは、「。py」ファイルから読み取られたプログラムよりも速く実行されません。「.pyc」または「.pyo」ファイルの方が高速なのは、ファイルの読み込み速度だけです。

.pycファイルを実行する利点は、Pythonを実行する前にコンパイルするオーバーヘッドをPythonが負担する必要がないことです。とにかく、Pythonは.pyファイルを実行する前にバイトコードにコンパイルするため、それ以外にパフォーマンスの向上はありません。

コンパイル済みの.pycファイルを使用することで、どの程度の改善が得られますか?それは、スクリプトの機能によって異なります。「Hello World」を出力するだけの非常に短いスクリプトの場合、コンパイルは、起動および実行時間全体の大部分を占める可能性があります。ただし、実行時間の合計に比べてスクリプトをコンパイルするコストは、実行時間の長いスクリプトでは少なくなります。

コマンドラインで指定したスクリプトが.pycファイルに保存されることはありません。その「メイン」スクリプトによってロードされたモジュールのみがその方法で保存されます。


3
多くの場合、違いを見分けるのは困難ですが、30万行を超える特定のpythonファイルがあります。(テスト用に別のスクリプトで生成された一連の数学計算です)コンパイルに37秒、実行にわずか2秒かかります。
wojtow 2017年

54

プラス:

まず、軽度で敗北可能な難読化です。

第二に、コンパイルの結果、ファイルが大幅に小さくなると、ロード時間が短縮されます。ウェブに最適です。

3番目:Pythonはコンパイル手順をスキップできます。初期ロードでより高速です。CPUとWebに最適です。

4番目:コメントが多いほど、.pycor .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して.pycor .pyoファイルではなくファイルを実行するかどうかを決定することに注意してください-.pyファイルを編集すると、.pycor .pyoは廃止され、得られたすべての利点が失われます。.pycまたはの.pyo利点を再度取得するには、再コンパイルする必要があります。

欠点:

最初に、Pythonファイルがコンパイルされたシステムアーキテクチャを示す「マジッククッキー」.pyc.pyoファイルがあります。これらのファイルの1つを別のタイプの環境に配布すると、壊れます。あなたが配布する場合.pycまたは.pyo関連することなく、.py再コンパイルしたりtouchして、それが取って代わります.pyc.pyoと、エンドユーザーも修正できません。

2番目:上記のコマンドラインオプションをdocstrings使用してスキップした場合、-OOその情報を誰も取得できなくなり、コードの使用がより困難(ま​​たは不可能)になる可能性があります。

3番目:Pythonの-OOオプションは、-Oコマンドラインオプションに従っていくつかの最適化も実装します。これにより、動作が変わる場合があります。既知の最適化は次のとおりです。

  • sys.flags.optimize = 1
  • assert ステートメントはスキップされます
  • __debug__ =偽

第四は:あなたが意図的にのために何かを使用してPythonスクリプトを実行可能にしていた場合#!/usr/bin/python、最初の行で、これはで取り除かれる.pyc.pyo、ファイルとその機能が失われます。

第5に、ある程度明白ですが、コードをコンパイルすると、その使用に影響が及ぶだけでなく、他の人があなたの作業から学ぶ可能性が大幅に減少します。


10

コンパイルされたpythonを実行するとパフォーマンスが向上します。ただし、インポートされたモジュールとして.pyファイルを実行すると、pythonはそれをコンパイルして保存します。.pyファイルが変更されない限り、常にコンパイルされたバージョンを使用します。

ファイルが使用されるとき、どんなinterpeted言語でも、プロセスは次のようになり
ます。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


9

すでに述べたように、Pythonコードをバイトコードにコンパイルすると、パフォーマンスが向上します。これは通常、インポートされたスクリプトに対してのみ、Python自体によって処理されます。

Pythonコードをコンパイルするもう1つの理由は、コピーや変更から知的財産を保護することです。

詳細については、Pythonのドキュメントをご覧ください。


2
コードの保護に関しては、コンパイルはあまり役に立ちません。難読化をコンパイルする-しかし、欲望を持つ誰かがあなたのコードを関係なく取得します。
Josh Smeaton、

1
@joshは常に可能です。十分な時間をかけてメモリにアクセスしたり、CPUへの指示を監視したりできれば、アプリを再構築できます。
UnkwnTech

5
しかし、Unkwntechが言ったように、人が十分に決意していれば、それは常に可能であることに同意しました。しかし、ほとんどの状況ではそれで十分だと確信しています。通常、ユーザーがコードを「修正」することを制限したいだけなのです...
Simon B. Jensen

バイトコードにコンパイルされる言語は、難読化するために追加の手順を実行しない限り通常、逆コンパイルがそれほど難しくありません。単にコンパイルするだけでは十分ではありません。
EJoshuaS-モニカを復活させる

7

コンパイルされたスクリプトを実行すると、確かにパフォーマンスの違いがあります。通常の.pyスクリプトを実行すると、マシンはスクリプトを実行するたびにコンパイルするため、時間がかかります。最近のマシンでは、これはほとんど目立ちませんが、スクリプトが大きくなるにつれて、問題になる可能性があります。


7

触れられていないものは、ソースからソースへのコンパイルです。例えば、nuitka PythonコードをC / C ++変換し、遅い仮想マシンで実行されるPythonバイトコードではなく、CPUで直接実行されるバイナリコードにコンパイルします。

これは大幅なスピードアップにつながる可能性があります。または、環境がC / C ++コードに依存しているときにPythonで作業できるようになります。


4

コンパイルされたコードを使用して、ソースコードにアクセスできないユーザーに配布します。基本的に、経験の浅いプログラマが誤って何かを変更したり、知らせずにバグを修正したりするのを防ぐため。


2

うん、パフォーマンスが主な理由であり、私の知る限り、唯一の理由です。

一部のファイルがコンパイルされない場合、おそらくディレクトリのアクセス許可などが原因で、Pythonが.pycファイルに書き込めない可能性があります。または、未コンパイルのファイルがロードされないだけかもしれません...(スクリプト/モジュールは、最初にロードされたときにのみコンパイルされます)


1

初心者は、.pycファイルのためにPythonがコンパイルされていると想定しています。.pycファイルはコンパイルされたバイトコードで、解釈されます。したがって、以前にPythonコードを実行したことがあり、.pycファイルが手元にある場合は、バイトコードを再コンパイルする必要がないため、2回目の実行の方が速くなります。

コンパイラー: コンパイラーは、高水準言語を機械語に変換するコードの一部です。

インタープリター: インタープリターは、高水準言語を機械可読バイナリー同等物に変換します。インタープリターは、実行する高水準言語コードを取得するたびに、コードを中間コードに変換してから、マシンコードに変換します。コードの各部分が解釈され、シーケンスで個別に実行され、コードの一部でエラーが検出されると、次のコードセットを変換せずにコードの解釈が停止します。

ソース: 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に「コンパイル」などと言う理由です。
リッキースチュワート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.