別の質問 で、受け入れられた回答は、パフォーマンスを改善するために、Pythonコードでtry/exceptブロックで(非常に安い)ifステートメントを置き換えることを提案しました。
コーディングスタイルの問題は別として、例外がトリガーされないと仮定すると、例外ハンドラーを持つことと、持たないこと、ゼロと比較するifステートメントを持つこととのパフォーマンスの違いはどれくらいありますか?
timeit
モジュール を使用して測定しないのはなぜですか?これにより、アプリケーションに関連するかどうかを確認できます。
OK、だから私は次のことを試しました:
_import timeit
statements=["""\
try:
b = 10/a
except ZeroDivisionError:
pass""",
"""\
if a:
b = 10/a""",
"b = 10/a"]
for a in (1,0):
for s in statements:
t = timeit.Timer(stmt=s, setup='a={}'.format(a))
print("a = {}\n{}".format(a,s))
print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))
_
結果:
_a = 1
try:
b = 10/a
except ZeroDivisionError:
pass
0.25 usec/pass
a = 1
if a:
b = 10/a
0.29 usec/pass
a = 1
b = 10/a
0.22 usec/pass
a = 0
try:
b = 10/a
except ZeroDivisionError:
pass
0.57 usec/pass
a = 0
if a:
b = 10/a
0.04 usec/pass
a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero
_
したがって、予想どおり、例外ハンドラを持たない方がわずかに高速です(ただし、例外が発生すると顔が爆破します)。また、_try/except
_は、条件が満たされない限り、明示的なif
よりも高速です。
しかし、それはすべて同じ桁の範囲内であり、どちらの方法でも問題になる可能性は低いです。条件が実際に満たされた場合にのみ、if
バージョンが大幅に高速になります。
この質問は、実際には Design and History FAQ で回答されています:
Try/exceptブロックは、例外が発生しない場合に非常に効率的です。実際に例外をキャッチするのは高価です。
この質問は誤解を招くものです。例外がneverトリガーであると仮定した場合、どちらも最適なコードではありません。
エラー条件の一部として例外がトリガーされると仮定した場合、最適なコードを必要とする領域の外に既にあります(おそらく、そのようなきめ細かいレベルでそれを処理していないでしょう)。
Pythonの「許可ではなく、許しを求める」方法である標準制御フローの一部として例外を使用している場合、例外がトリガーされ、コストは例外の種類、ifの種類に依存します、例外が発生すると推定する時間の割合。