python - 为什么三元运算符比 .get 更快?

标签 python python-2.7 dictionary

我最近发现了一些令人惊讶的事情。给定一个不包含键 k 的字典 d,使用三元运算符尝试检索具有默认返回值的项目:

>>> def tern():
...     d[k] if k in d else 'foo'
...
>>> timeit.timeit(tern, number=1000000)
0.12342095375061035

比字典的 .get() 函数运行得更快:

>>> def get_meth():
...     d.get(k, 'foo')
...
>>> timeit.timeit(get_meth, number=1000000)
0.20549297332763672

这对我来说似乎违反直觉。我认为三元运算符需要通过 dict 进行 2 次搜索(一次用于测试 k in d),然后另一个用于检索 d[k],而 .get 将简单地尝试检索 d[k],如果失败,则返回 'foo'

我在一个大的字典(一百万个元素)和一个小的字典(100 个)上运行了这个,两次,三元都快得多。这里的幕后发生了什么?

最佳答案

如果你反汇编这两个方法,你会看到 get 有一个额外的 CALL_FUNCTION ,与 POP_JUMP_IF_FALSE 相比,这在 python 中是昂贵的说明。

如果在

  3           0 LOAD_CONST               1 ('blub')
              3 LOAD_GLOBAL              0 (d)
              6 COMPARE_OP               6 (in)
              9 POP_JUMP_IF_FALSE       22
             12 LOAD_GLOBAL              0 (d)
             15 LOAD_CONST               1 ('blub')
             18 BINARY_SUBSCR       
             19 JUMP_FORWARD             3 (to 25)
        >>   22 LOAD_CONST               2 ('foo')
        >>   25 POP_TOP             
             26 LOAD_CONST               0 (None)
             29 RETURN_VALUE        

获取方法:

  6           0 LOAD_GLOBAL              0 (d)
              3 LOAD_ATTR                1 (get)
              6 LOAD_CONST               1 ('blub')
              9 LOAD_CONST               2 ('foo')
             12 CALL_FUNCTION            2          #Expensive call
             15 POP_TOP             
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE        

前段时间我读了一篇很长的文章,其中有一节描述了为什么 CALL_FUNCTION 如此昂贵: https://doughellmann.com/blog/2012/11/12/the-performance-impact-of-using-dict-instead-of-in-cpython-2-7-2/

关于python - 为什么三元运算符比 .get 更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47914610/

相关文章:

python - 如果字典中的键重复,如何引发错误

c# - 绑定(bind)到字典的 DataGridView

python - 如何合并嵌套字典?

python - Tensorflow 版本 0.12 中 tf.Variable.ref() 的替代方案是什么?

python - 使用 BeautifulSoup 问题抓取数据

python - tqdm 打印到换行符

python - 使用 spaCy 训练 NER 时损失平稳

python - 如何在 python 中将完整输出写入文件而不附加

python - 在 python 中集成 OCaml - 如何从 python 中保持 ocaml session ?

python - 使用 skimage 导入过滤器时出现问题