简短答案:
- 在python 2中:您的假设是正确的:
dict.keys()
放慢速度。 - 在python 3中:您的假设不正确:
in dict.keys()
像in dict
py2和py3的详细信息如下。
Python 2.7答案:
您的假设是正确的,原因如下:
dict.keys()
涉及额外的函数调用(堆栈开销)。dict.keys()
返回一个列表,其中包含内存中的所有键(与惰性生成器对象相对)。因此,它需要分配内存。key in dict
可以在内部使用set对象,这是索引查找。key in dict.keys()
是列表中的线性搜索
我创建了一个小的benckmark脚本来说明我的观点:
#! /usr/bin/python2.7import datetime as dtimport randomdict_size = 1000000num_iterations = 100d = {i: i for i in xrange(dict_size)}def f(): k = random.randint(0,dict_size-1) return (k in d)def g(): k = random.randint(0,dict_size-1) return (k in d.keys())def test(func): t = dt.datetime.utcnow() for i in xrange(num_iterations): func() print "%s --> %1.6f s" % (func, (dt.datetime.utcnow()-t).total_seconds())test(f)test(g)输出(python 2.7.6 Ubuntu 14.04):
<function f at 0x7ff2e0126d70> --> 0.000598 s<function g at 0x7ff2e0126de8> --> 5.191553 s
我还测试了nr次迭代和dict大小交换(仅100个项目的dict,1M次迭代)。
<function f at 0x7f94cb5e6d70> --> 3.614162 s<function g at 0x7f94cb5e6de8> --> 7.007922 s
这里的结果更加接近。
因此,性能差异确实随字典大小的增加而增加。
Python 3答案:
我为python 3修改了脚本:
xrange
不见了,range
取而代之。(不在测试功能的性能至关重要的内部循环中,因此对性能的影响有限)- 用大括号
print
- 更改沙邦线为
#!/usr/bin/python3
并在同一台机器上使用python 3.4.3进行了测试。
- dict_size = 1000000; num_iterations = 100
f-> 0.000590 s g-> 0.000565 s
- dict_size = 100; num_iterations = 1000000
f-> 4.525487 s g-> 4.837232 s
因此,在python 3中,性能差异消失了。



