コードの最適化を検討する中で、Python でどちらがより高価なのか疑問に思っていました。
if x:
d = 1
else:
d = 2
また
d = 2
if x:
d = 1
何かご意見は?2 番目の行数の削減は気に入っていますが、条件の切り替えよりも再割り当ての方がコストがかかるのではないかと思いました。
コードの最適化を検討する中で、Python でどちらがより高価なのか疑問に思っていました。
if x:
d = 1
else:
d = 2
また
d = 2
if x:
d = 1
何かご意見は?2 番目の行数の削減は気に入っていますが、条件の切り替えよりも再割り当ての方がコストがかかるのではないかと思いました。
熟考せず、疑問に思わず、測定してください--timeit
シェル コマンド ラインで(これを使用するための最良の、最も簡単な方法です!)。ラップトップ上の Mac OSX 10.5 上の Python 2.5.4...:
$ python -mtimeit -s'x=0' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0748 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0685 usec per loop
$ python -mtimeit -s'x=0' 'd=2' 'if x: d=1'
10000000 loops, best of 3: 0.0734 usec per loop
$ python -mtimeit -s'x=1' 'd=2' 'if x: d=1'
10000000 loops, best of 3: 0.101 usec per loop
ご覧のとおり、「if/else」形式と比較して、x が false の場合、「just-if」形式は 1.4 ナノ秒節約できますが、x が true の場合は 40.2 ナノ秒かかります。したがって、マイクロ最適化のコンテキストでは、x が true よりも false である可能性が 30 倍程度高い場合にのみ、前者を使用する必要があります。また:
$ python -mtimeit -s'x=0' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0736 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.076 usec per loop
...if/else の三項演算子には、独自の小さなプラスとマイナスがあります。
違いがこのように小さい場合は、繰り返し測定し、ノイズ レベルを確認し、「ノイズ内」の違いを重要視していないことを確認する必要があります。たとえば、「x が true」の場合にステートメントと式の if/else を比較するには、それぞれ数回繰り返します。
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.076 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0749 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0742 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0749 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0745 usec per loop
これで、式の形式が (このマシンと主要なソフトウェアのバージョンで) 74.2 から 76.0 ナノ秒かかると述べることができます。この範囲は、単一の数値よりもはるかに表現力豊かです。同様に:
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0688 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0681 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0687 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0679 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0692 usec per loop
これで、ステートメント形式が (同じ条件下で) 67.9 から 69.2 ナノ秒かかることを自信を持って述べることができます。したがって、x true の場合、式形式に関して、その利点は 4.8 から 8.1 ナノ秒です (この後者の間隔推定を 6.3 から 6.8 ナノ秒に制限し、min/max と max/ の代わりに min/min と max/max を比較するのはかなり公平です)。より広く、より慎重な見積もりと同じように最小)。
そのような微視的な違いにどれだけの時間とエネルギーを費やす価値があるかは、もちろん、それらが微視的であることに気付いた場合、別の問題です.
おそらくこれをベンチマークする必要がありますが、三項演算子を使用する 3 番目の形式もあります。
d = 1 if x else 2
2 番目のものは明らかによりコストがかかるはずです。false の場合x
は同じ操作を行い、true の場合は 2 倍の代入を行いx
ます。
仮定: Python では、代入は条件付きジャンプよりもコストがかかります。これは、解釈され、新しい値を取得するためにランタイム ハッシュを読み取ってから、同じハッシュでアップロードする必要があるため、理にかなっています。
私は、最も読みやすいものが最も最適化されていると主張します(少なくとも読みやすさのために)。
if...else コンストラクトは、どちらかまたは両方のケースを扱っていることを明確にします。
(d==2) が通常の値であり、if が異常なケースをテストする場合、代入構文はより理にかなっている可能性があります。代入が if から遠ざかると、この構造は不明確になります。
この単純な例では、実際には問題になりません。より複雑なコードの場合、ほとんどの場合、CPU サイクルを数回犠牲にしても、読みやすさを最適化します。