繁体   English   中英

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

[英]Why is "try ... except KeyError ..." slower than "dict.get"?

很久以前,有人告诉我

d = {}
try:
    a = d['a']
    # do something
except KeyError:
    # do something else

a = d.get('a')
if a:
    # do something
else:
    # do something else

但是今天,我做了一个简单的测试后,发现结果恰恰相反:

import time

d = {}
n = 0
t1 = time.time()
for i in range(1000000):
    try:
        a = d['a']
    except KeyError:
        n += 1
print(time.time() - t1)
>>> 0.4676947593688965
import time

d = {}
n = 0
t1 = time.time()
for i in range(1000000):
    a = d.get('a')
    if a is None:
        n += 1
print(time.time() - t1)
>>> 0.3045947551727295

那为什么会这样呢? 在我的想象中, d.get也应该做类似的逻辑判断键是否存在于字典中。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM