低于Slice和手动反向操作之间的性能差异。如果是这种情况,那是什么原因?
timeit.timeit("a[::-1]","a=[1,2,3,4,5,6]",number=100)
6.054327968740836e-05
timeit.timeit("[a[i] for i in range(len(a)-1,-1,-1)]","a=[1,2,3,4,5,6]",number=100)
0.0003132152330920235
答案 0 :(得分:8)
这里是字节码
from dis import dis
a = [1,2,3,4,5,6]
def func1():
a[::-1]
def func2():
[a[i] for i in range(len(a)-1,-1,-1)]
def func3():
reversed(a)
在第二种方法中,您可以找到长度,创建一个带范围的副本并创建变量i。
也可以使用reverse来创建一个可迭代的。
答案 1 :(得分:2)
用于反转列表的切片表示法下降到C,这比反向的纯python实现要快得多。例如,在纯python方法中,python解释器必须读取,解码和执行字节代码中的每个指令,而C调用将本地执行并且不会受到这样的惩罚。这种惩罚还扩展到诸如索引项目时的方法查找等等,而在C调用中没有方法,只有地址算术。如此高效的C实现它甚至不需要专门的反向切片功能,并且仍然胜过纯python实现。相反,它会创建切片的副本并将切片反转到位(在其他地方完成)。
static PyObject *
list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
PyListObject *np;
PyObject **src, **dest;
Py_ssize_t i, len;
if (ilow < 0)
ilow = 0;
else if (ilow > Py_SIZE(a))
ilow = Py_SIZE(a);
if (ihigh < ilow)
ihigh = ilow;
else if (ihigh > Py_SIZE(a))
ihigh = Py_SIZE(a);
len = ihigh - ilow;
np = (PyListObject *) PyList_New(len);
if (np == NULL)
return NULL;
src = a->ob_item + ilow;
dest = np->ob_item;
for (i = 0; i < len; i++) {
PyObject *v = src[i];
Py_INCREF(v);
dest[i] = v;
}
return (PyObject *)np;
}
答案 2 :(得分:0)
3种不同版本的反汇编 - (无屏幕截图):
import dis
a = [1,2,3,4,5,6]
def x( l ):
return l[::-1]
dis.dis(x)
2 0 LOAD_FAST 0 (l)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 1 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
def y( l ):
return [l[i] for i in range(len(l)-1,-1,-1)]
dis.dis(y)
2 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (len)
9 LOAD_FAST 0 (l)
12 CALL_FUNCTION 1
15 LOAD_CONST 1 (1)
18 BINARY_SUBTRACT
19 LOAD_CONST 2 (-1)
22 LOAD_CONST 2 (-1)
25 CALL_FUNCTION 3
28 GET_ITER
>> 29 FOR_ITER 16 (to 48)
32 STORE_FAST 1 (i)
35 LOAD_FAST 0 (l)
38 LOAD_FAST 1 (i)
41 BINARY_SUBSCR
42 LIST_APPEND 2
45 JUMP_ABSOLUTE 29
>> 48 RETURN_VALUE
def z( l ):
return [i for i in reversed(a)]
dis.dis(z)
2 0 BUILD_LIST 0
3 LOAD_GLOBAL 0 (reversed)
6 LOAD_GLOBAL 1 (a)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 12 (to 28)
16 STORE_FAST 1 (i)
19 LOAD_FAST 1 (i)
22 LIST_APPEND 2
25 JUMP_ABSOLUTE 13
>> 28 RETURN_VALUE