dict.__setitem__(key,x)比dict[key]=x慢(或快)吗?为什么



我发现了一些奇怪的东西。

我定义了两个测试函数:

def with_brackets(n=10000):
d = dict()
for i in range(n):
d["hello"] = i
def with_setitem(n=10000):
d = dict()
st = d.__setitem__
for i in range(n):
st("hello", i)

人们期望这两个函数的执行速度大致相同。但是:

>>> timeit(with_brackets, number=1000)
0.6558860000222921
>>> timeit(with_setitem, number=1000)
0.9857697170227766

我可能错过了一些东西,但似乎setitem的长度几乎是它的两倍,我真的不明白为什么。dict[key]=x不是应该调用__setitem__吗?

(使用CPython 3.9(

编辑:使用timeit而不是时间

dict[key] = x不应该调用__setitem__吗?

严格来说,不是。通过dis.dis运行您的两个函数,我们得到(我只包括for循环(:

>>> dis.dis(with_brackets)
...
>>   22 FOR_ITER                12 (to 36)
24 STORE_FAST               3 (i)
5          26 LOAD_FAST                0 (n)
28 LOAD_FAST                1 (d)
30 LOAD_CONST               1 ('hello')
32 STORE_SUBSCR
34 JUMP_ABSOLUTE           22
...

>>> dis.dis(with_setitem)
...
>>   28 FOR_ITER                14 (to 44)
30 STORE_FAST               4 (i)
6          32 LOAD_FAST                2 (setitem)
34 LOAD_CONST               1 ('hello')
36 LOAD_FAST                0 (n)
38 CALL_FUNCTION            2
40 POP_TOP
42 JUMP_ABSOLUTE           28
...

__setitem__的使用涉及到一个函数调用(请参阅CALL_FUNCTIONPOP_TOP的使用,而不仅仅是STORE_SUBSCR——这是隐藏的区别(,并且函数调用确实会增加一些开销,因此使用括号访问器可以获得更优化的操作码。

最新更新