122

別の質問で、受け入れられた回答は、パフォーマンスを向上させるために、Python コードの (非常に安価な) if ステートメントを try/except ブロックに置き換えることを提案しました。

コーディング スタイルの問題はさておき、例外が決してトリガーされないと仮定すると、例外ハンドラーがある場合とない場合、またはゼロと比較する if ステートメントがある場合とでは、(パフォーマンスに関して) どのくらいの違いがありますか?

4

5 に答える 5

133

timeitモジュールを使って測定してみませんか?そうすれば、それがアプリケーションに関連しているかどうかを確認できます。

わかりましたので、次のことを試しました。

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バージョンは大幅に高速になります。

于 2010-03-26T08:54:50.650 に答える
75

この質問は、実際にはDesign and History FAQで回答されています。

例外が発生しない場合、try/except ブロックは非常に効率的です。実際に例外をキャッチするにはコストがかかります。

于 2010-03-27T14:56:19.770 に答える
20

この質問は誤解を招きます。例外がトリガーされないと仮定すると、どちらも最適なコードではありません。

例外がエラー状態の一部としてトリガーされたと想定する場合、最適なコードを必要とする領域から既に外れています (とにかく、そのような細かいレベルで処理していない可能性があります)。

標準の制御フローの一部として例外を使用している場合 (これは Pythonic の「許可ではなく許しを求める」方法です)、例外がトリガーされ、コストは例外の種類、if の種類によって異なります。 、および例外が発生すると見積もる時間の割合。

于 2010-09-18T21:12:39.553 に答える