Python中异常处理程序的成本

时间:2010-03-26 08:52:21

标签: python performance exception micro-optimization

another question中,接受的答案建议用try / except块替换Python代码中的(非常便宜的)if语句,以提高性能。

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

4 个答案:

答案 0 :(得分:87)

为什么不使用timeit module进行衡量?这样你就可以看出它是否与你的应用程序相关。

好的,所以我刚刚尝试了以下内容:

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版本才会明显加快。

答案 1 :(得分:46)

这个问题实际上已在 Design and History FAQ

中得到解答
  

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

答案 2 :(得分:14)

这个问题具有误导性。如果您认为异常是从不触发,则两者都不是最佳代码。

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

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

答案 3 :(得分:1)

在 Python 3.11 中,

“Zero-cost” exceptions are implemented. The cost of try statements is almost eliminated when no exception is raised. (Contributed by Mark Shannon in bpo-40222.)

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