为什么使用切片对列表进行浅层复制比使用list
内置文件快得多?
In [1]: x = range(10)
In [2]: timeit x_ = x[:]
10000000 loops, best of 3: 83.2 ns per loop
In [3]: timeit x_ = list(x)
10000000 loops, best of 3: 147 ns per loop
通常当我看到这样奇怪的事情时,它们会在python3中修复 - 但这种差异仍然存在:
In [1]: x = list(range(10))
In [2]: timeit x_ = x[:]
10000000 loops, best of 3: 100 ns per loop
In [3]: timeit x_ = list(x)
10000000 loops, best of 3: 178 ns per loop
答案 0 :(得分:9)
区别在于额外的函数调用(只有SLICE+0
vs CALL_FUNCTION 1
额外的堆栈操作):
>>> import dis
>>> def f(lst):
... return lst[:]
...
>>> def f1(lst):
... return list(lst)
...
>>> dis.dis(f)
2 0 LOAD_FAST 0 (lst)
3 SLICE+0
4 RETURN_VALUE
>>> dis.dis(f1)
2 0 LOAD_GLOBAL 0 (list)
3 LOAD_FAST 0 (lst)
6 CALL_FUNCTION 1
9 RETURN_VALUE
来自dis docs:
<强> SLICE + 0()强>
实现TOS = TOS [:]。
(TOS - 堆栈顶部)
<强> CALL_FUNCTION(argc个)强>
调用一个函数。 argc的低字节表示 位置参数的数量,高字节的数量 关键字参数。在堆栈上,操作码找到关键字 参数首先。对于每个关键字参数,值都在上面 钥匙。在关键字参数下方,位置参数是 在堆栈上,最右边的参数位于顶部。以下 参数,要调用的函数对象在堆栈上。一切都流行起来 函数参数,以及函数本身离开堆栈,并推送 返回值。