2009-11-07 9 views
42

Pythonには、インタプリタを実行できるフラグ-Oがあります。このオプションは "最適化された"バイトコード(.pyoファイルに書き込まれます)を生成し、2回指定するとドキュメントストリングが破棄されます。 Pythonのマニュアルページから:Pythonの基本的な最適化モードの使い方は? (python -O)

-O基本的な最適化をオンにします。コンパイル(バイトコード)ファイルのファイル拡張子 が.pycから.pyoに変更されます。二度与えられた場合、 はドキュメントストリングを破棄します。私はそれを見るよう

このオプションの二つの主要な機能は次のとおりです。

  • ストリップすべての文を主張しています。これは、スピードのために不正なプログラム状態に対する防御を兼ね備えています。しかし、違いを生み出すために、あなたは大量の主張の声明を必要としませんか?これが価値のあるコード(コード)がありますか?

  • ストリップすべてのドキュメントストリング。どのアプリケーションでメモリ使用量が非常に重要であるか、これが勝利ですか?なぜCで書かれたモジュールにすべてを押し込まないのですか?

このオプションの用途は何ですか? 実際の価値はありますか?

+5

テストスイート上の明滅ライトを反転させて、アサーションを慎重に無視させることができます。ハレイ!あなたはプロジェクトを終えました! (注:これをしないでください) – Shayne

答えて

29

アサート・ステートメントを削除する:ASSERTの定義の一部が実動コードで実行されないと多くの人が信じているCの世界で標準的なオプションです。違いは、それらを除去するかどうかは、それらがそう主張するどのくらいの仕事に比べてありますどのように多くのアサートにあまり依存:

def foo(x): 
    assert x in huge_global_computation_to_check_all_possible_x_values() 
    # ok, go ahead and use x... 

はほとんどもちろんのこと、似ていない主張するが、それはあなたのことを覚えておくことが重要ですそのようなことをすることができます。

ドキュメントストリングを取り除くのは、メモリが制約された環境で違いが出るかもしれませんが、単純な時間から気まずいホールドオーバーのように見えます。

+0

歴史は重要です、良い点。しかし、私はおもちゃの例を見たいと思っていません、私は実際のコードで使われているものが何であるかを見たいと思っています。 – u0b34a0f6ae

+17

メモリの速度はCPUの速度よりもはるかに遅くなっています。したがって、メモリは新しいディスクであり、L2キャッシュは新しいメモリです。そして、L2キャッシュは(メモリと比較して)小さくて、実際には小さくなっています。 (Core2には6144KiB、i7には256KiBしかありません)。したがって、実際にはバイトを数えることは、再び有用になっています。 –

+2

-Oを指定しない限り、PyOpenGLやpygletのようなOpenGLライブラリは、実行時に非常に高価な安全性チェックアサーションを行います。 –

3

あなたはそれを理解しました。実際には何もしません。あなたは、RAMをひどく傷つけている場合を除き、スピードやメモリの利益をほとんど目にしません。

+0

または 'if __debug__:r = long_running_function(); n - 0.01 DylanYoung

5

-Oの最も重いユーザーはpy2exepy2appなどと想像します。

私は個人的に直接-Oの使用を発見していません。

+0

*なぜ* py2exeはそれを使用しますか? – u0b34a0f6ae

+4

スタンドアロンの実行可能ファイルを作成する場合、ドキュメントストリングは必要ありません。彼らはメモリ内のスペースを取るだけです。 – gnud

7

頻繁に呼び出されるコード(アウターループなど)にアサーションがある場合、それらを削除することで確かに効果が得られます。極端な例:

$ python -c 'import timeit;print timeit.repeat("assert True")' 
[0.088717937469482422, 0.088625192642211914, 0.088654994964599609] 
$ python -O -c 'import timeit;print timeit.repeat("assert True")' 
[0.029736995697021484, 0.029587030410766602, 0.029623985290527344] 

実際のシナリオでは、通常節約はずっと少なくなります。

ドキュメントストリングを削除すると、コードのサイズが小さくなり、作業セットが小さくなる可能性があります。

多くの場合、パフォーマンスへの影響はごくわずかですが、常に最適化を行うと、必ず測定するだけです。

+1

この質問は実際のコードについてです。これはもっと実用的です: 'python -mtimeit" "" assert(True) "'(最初の引数で設定します) – u0b34a0f6ae

+1

これは私にとって奇妙な例です。私が考える実用的な速度の向上についてはあまり示されていない、非存在でないコードには些細なコードを減らします。現実的なユースケースは、操作を実行するのに比べてチェックするのに費用がかかる多くの仮定を行う操作ですが、常に満足する必要があると考えています。例えば、私が放物線の根を返そうとしているなら、本当の根を確実にするためにb ** 2 - 4 * a * c> 0を調べることができます。の制約。 –

+2

また、 'assert'は' assert(True) 'ではなく' assert True'のように使われることを意図した文です。これは、 'assert a == b 'のようにメッセージを追加するときに重要になります。本当でなければならないのは、' assert(a == b、 "真でなければならない") 'とは大きく異なります。 。 –

6

-Oを使用する正当な理由はありませんでした。私はいつもその主な目的は、ある意味で、意味のある最適化が追加されていることを前提としています。

+3

さて、それはいくつかのことをしますが、それらは一般的にはそれほど有用ではありません。 –

39

-Oフラグの別の使用法は、__debug__組み込み変数の値がFalseに設定されていることです。

だから、基本的に、あなたのコードのような「デバッグ」パスの多くを持つことができます。

-Oの下で実行している場合でも .pyoファイル内のバイトコードに含まれることはありません、
if __debug__: 
    # output all your favourite debugging information 
    # and then more 

。貧しい人のC-ish #ifdef。

フラグが-OOの場合、ドキュメントストリングはにのみドロップされることに注意してください。

+1

私は-Oのもう一つの根本的な問題を考えるようになります:一般的に、最適化モードの有無にかかわらず何が起きるかは、開発者の役割ですが、Pythonインタプリタの呼び出し方法を決めることができます。これは、使用されている特定のモードに頼ることができないので、役に立たない次の例になります。 – u0b34a0f6ae

+22

うわー。私は、あなたがこのオプションの実際の使用が何であるかを知りたいと思ったと思いました。役に立たないの隣に私の答えを見つけることに感謝します。ちなみに、誰かがGuidoとPythonコアチームの選択を正当化するようにしたいのであれば、ここで質問するべきではありません。最後に、使用されている特定のモードに依存することができます。プログラマは、最適化が使用されているかどうかを制御できます。どのようにSOの関連する質問をしてください。私はあなたの前提を間違っていると宣言し、次に私の時間を失ったと宣言します。乾杯。あなたを失望させて申し訳ありません。 – tzot

+3

私の質問に多くの回答を得ることに失望する理由はありません。私は、stackoverflowの会話が好きです。私が言うことを意味しますが、あなたが示した例について話します。あなたがそれを示したという事実、またはあなた自身が否定的に判断されることはありません。 – u0b34a0f6ae

1

しかし、これを変更するには、これに大量のアサーションステートメントが必要ですか?

例として、グラフのノード間のパスを取得するコードがあります。私は、パスが重複が含まれていないことを確認するために、関数の最後でassert文を持っている:

assert not any(a == b for a, b in zip(path, path[1:])) 

私はこの単純な文は、開発中に与えることpeace of mind and clarityが好き。本番では、コードはいくつかの大きなグラフを処理し、この1行は実行時間の66%を占めることがあります。したがって、-Oで実行すると、大幅なスピードアップが可能になります。

関連する問題