Python中异常处理程序的成本

Thi*_*ilo 84 python performance exception micro-optimization

另一个问题中,接受的答案建议用try/except块替换Python代码中的(非常便宜的)if语句以提高性能.

抛开编码样式问题,并假设从未触发异常,与异常处理程序相比,具有异常处理程序(与性能相比)有多大差异,而不是具有比较为零的if语句?

Tim*_*ker 97

你为什么不用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))
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)

因此,正如预期的那样,没有任何异常处理程序会稍微快一点(但是当异常发生时会在你的脸上爆炸),并且只要条件不满足就try/except比表达更快if.

但它都在同一数量级内,并且不论两种方式都不太重要.只有在满足条件的情况下,if版本才会明显加快.

  • @S.洛特:你是什么意思?他没有问,他发了言.但是,我把代码从`if a!= 0:`改为`if a:`之后他写了他的评论(顺便说一下,这对性能没有影响).也许这就是造成误解的原因? (18认同)
  • 啊,一个很好的词语选择:"它都在同一个数量级内"......我怀疑许多避免异常的人都这样做,期望它们的速度是10倍. (7认同)
  • 有趣。所以`try / except`比`if!= 0更快 (2认同)

Mic*_*ael 50

这个问题实际上在设计和历史常见问题中得到了回答:

如果没有引发异常,try/except块非常有效.实际上捕获异常是昂贵的.

  • 我只是想知道"极其高效"的效率如何.显然它甚至比一个非常简单的"if"语句更快. (2认同)

Sup*_*ova 27

在Python 3.11中,

\n

\xe2\x80\x9cZero-cost\xe2\x80\x9d exceptions are implemented. The cost of try statements is almost eliminated when no exception is raised. (Contributed by Mark Shannon in bpo-40222.)

\n

https://docs.python.org/3.11/whatsnew/3.11.html#optimizations

\n


小智 16

这个问题具有误导性.如果您假设永远不会触发异常,则两者都不是最佳代码.

如果您认为异常是作为错误条件的一部分触发的,那么您已经超出了想要最佳代码的范围(并且您可能无论如何都不会在这样的细粒度级别处理它).

如果你使用异常作为标准控制流程的一部分 - 这是Pythonic"请求宽恕,而不是许可"的方式 - 然后将触发异常,并且成本取决于异常的类型,if的类型,以及你估计异常发生的时间百分比.


Hun*_*phu 7

问:try/catchPython 的成本高吗?

当我使用 try catch 时我应该担心吗?以什么方式?

这只是已经给出的答案的摘要。

A:有异常的时候if要快很多。否则不行。

@SuperNova 写道,异常的成本为零,因此它比没有异常时使用 if 语句更快。然而,处理异常的成本很高,因此:

对可能失败的事情使用 try。如果可能的话,避免尝试你知道会失败的事情

例子:
  1. 好的案例,使用试试:
try:
    x = getdata() # an external function 
except:
    print('failed. Retrying')
Run Code Online (Sandbox Code Playgroud)
  1. 不好的情况,这里 if-version 是首选:
try:
    x = getdata() # an external function 
except:
    print('failed. Retrying')
Run Code Online (Sandbox Code Playgroud)