Python 常见问题解答:“异常有多快?”

2024-06-28

我只是在看Python常见问题解答,因为它在另一个问题中提到了。以前从未真正详细地看过它,我发现这个问题 http://docs.python.org/3/faq/design.html#how-fast-are-exceptions:“异常有多快?”:

try/ except 块非常高效。实际上捕获异常是昂贵的。在 2.0 之前的 Python 版本中,通常使用以下习惯用法:

try:
    value = mydict[key]
except KeyError:
    mydict[key] = getvalue(key)
    value = mydict[key]

我有点惊讶“捕获异常的成本很高”部分。这仅指那些except您实际上将异常保存在变量中的情况,或者通常是所有异常excepts(包括上例中的那个)?

我一直认为使用所示的习惯用法会非常 Pythonic,尤其是在 Python 中“请求宽恕比获得许可更容易”。 SO上的很多答案也普遍遵循这个想法。

捕获异常的性能真的那么差吗?在这种情况下,人们是否应该遵循 LBYL(“三思而后行”)?

(请注意,我并不是直接讨论常见问题解答中的示例;还有许多其他示例,您只需查找异常而不是之前检查类型。)


捕获异常is昂贵,但应该有例外异常的(阅读,不经常发生)。如果例外情况很少见,try/catch比 LBYL 更快。

以下示例在键存在和不存在时使用异常和 LBYL 对字典键查找进行计时:

import timeit

s = []

s.append('''\
try:
    x = D['key']
except KeyError:
    x = None
''')

s.append('''\
x = D['key'] if 'key' in D else None
''')

s.append('''\
try:
    x = D['xxx']
except KeyError:
    x = None
''')

s.append('''\
x = D['xxx'] if 'xxx' in D else None
''')

for i,c in enumerate(s,1):
    t = timeit.Timer(c,"D={'key':'value'}")
    print('Run',i,'=',min(t.repeat()))

Output

Run 1 = 0.05600167960596991       # try/catch, key exists
Run 2 = 0.08530091918578364       # LBYL, key exists (slower)
Run 3 = 0.3486251291120652        # try/catch, key doesn't exist (MUCH slower)
Run 4 = 0.050621117060586585      # LBYL, key doesn't exist

当通常情况也不例外时,try/catch与 LBYL 相比“极其高效”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 常见问题解答:“异常有多快?” 的相关文章

随机推荐