为了账号安全,请及时绑定邮箱和手机立即绑定

为什么“try ... except KeyError ...”比“dict.get”慢?

为什么“try ... except KeyError ...”比“dict.get”慢?

绝地无双 2023-01-04 16:05:10
很久以前,有人告诉我d = {}try:    a = d['a']    # do somethingexcept KeyError:    # do something else比a = d.get('a')if a:    # do somethingelse:    # do something else但是今天,我做了一个简单的测试后,发现结果恰恰相反:import timed = {}n = 0t1 = time.time()for i in range(1000000):    try:        a = d['a']    except KeyError:        n += 1print(time.time() - t1)>>> 0.4676947593688965import timed = {}n = 0t1 = time.time()for i in range(1000000):    a = d.get('a')    if a is None:        n += 1print(time.time() - t1)>>> 0.3045947551727295那为什么会这样呢?在我的想象中,d.get也应该做类似的判断键是否存在于dict中的逻辑。
查看完整描述

1 回答

?
MM们

TA贡献1886条经验 获得超2个赞

当例外情况是不常见情况时,您所学的规则适用。如果您通常要查找该值,那么d['a']包装在很少调用异常处理机制的try/except KeyError:中将会获胜;如果您通常不会找到该值,则抛出和捕获异常的开销将超过使用泛型方法 dispatch ( d.get('a')) 与更直接的语法支持方法 ( ) 相比更高的相对开销d['a']。在现代 (3.7+) CPython 中尤其如此,其中方法调用得到了一些额外的优化,减少了d.get('a').

正如您在评论中指出的那样,在查找成功的情况下,get速度保持相同,而未d['a']使用的except KeyError:速度明显更快。在许多情况下它也更正确;如果dict有映射到 的键None,您get的基于 的代码将不会区分“键未找到”和“键映射到None”,这可能是您想要的,但通常不是。


查看完整回答
反对 回复 2023-01-04
  • 1 回答
  • 0 关注
  • 95 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信