pok*_*oke 14 python performance exception try-catch
我只是在看Python常见问题,因为它在另一个问题中提到过.我之前从未真正详细地看过它,但我遇到了这个问题:"异常有多快?":
try/except块非常有效.实际上捕获异常是昂贵的.在2.0之前的Python版本中,通常使用这个习惯用法:
Run Code Online (Sandbox Code Playgroud)try: value = mydict[key] except KeyError: mydict[key] = getvalue(key) value = mydict[key]
我对"捕获异常是昂贵的"部分感到有些惊讶.这是指那些except实际将异常保存在变量中的情况,或者通常是所有excepts(包括上例中的那个)的情况?
我一直认为使用这样的习语会非常pythonic,特别是在Python中"请求宽恕比获得权限更容易".关于SO的许多答案通常都遵循这个想法.
捕获异常的性能真的那么糟糕吗?在这种情况下,是否应该遵循LBYL("在你跳跃之前看")?
(请注意,我并没有直接讨论FAQ中的示例;还有许多其他示例,您只需注意异常而不是之前检查类型.)
Mar*_*nen 20
捕获异常是昂贵的,但异常应该是例外(读取,不经常发生).如果例外很少,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()))
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
当通常情况也不例外try/catch时,与LBYL相比,"非常有效".
显然,成本取决于实施,但我不担心.无论如何,它不太可能重要.标准协议会在最奇怪的地方引发异常(想想StopIteration),所以无论你喜欢与否,你都会被提升和捕捉.
在LBYL和EAFP之间进行选择时,要担心代码的可读性,而不是关注微优化.如果可能的话,我会避免类型检查,因为它可能会降低代码的通用性.
| 归档时间: |
|
| 查看次数: |
4307 次 |
| 最近记录: |