Why is copying a list using a slice[:] faster than using the obvious way?

跟風遠走 提交于 2019-12-22 01:53:47

问题


Why is shallow-copying a list using a slice so much faster than using list builtin?

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

Usually when I see weird things like this, they're fixed in python3 - but this discrepancy is still there:

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

回答1:


The difference is in additional function call (just SLICE+0 vs CALL_FUNCTION 1 with extra stack operations):

>>> 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 

From dis docs:

SLICE+0()
Implements TOS = TOS[:].

(TOS - top of stack)

CALL_FUNCTION(argc)
Calls a function. The low byte of argc indicates the number of positional parameters, the high byte the number of keyword parameters. On the stack, the opcode finds the keyword parameters first. For each keyword argument, the value is on top of the key. Below the keyword parameters, the positional parameters are on the stack, with the right-most parameter on top. Below the parameters, the function object to call is on the stack. Pops all function arguments, and the function itself off the stack, and pushes the return value.



来源:https://stackoverflow.com/questions/22796138/why-is-copying-a-list-using-a-slice-faster-than-using-the-obvious-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!