Poniżej różnicy wydajności między pokrojoną i ręczną odwrotną obsługą. Jeśli tak jest, jaki jest to powód?
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
3 odpowiedzi
Oto ByteCode
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)
W drugiej metodzie znajdujesz długość, tworząc kopię z zakresem i tworzenie zmiennej I.
Może również użyć odwrócenia, aby utworzyć iterable.
Plastry notation do odwracania listy spada w C, co jest znacznie szybsze niż czysta implementacja odwrotna. Na przykład, w czystym podejściu Python, tłumacz Pythona musi odczytywać, dekodować i wykonać każdą instrukcję w kodzie bajtowym, podczas gdy wezwanie C będzie wykonywać natywnie i nie cierpienia takiej kary. Ta kara rozciąga się również na takie rzeczy jak wyszukiwanie metod przy indeksowaniu przedmiotu i tak dalej, podczas gdy w połączeniu C nie ma sposobu, tylko adres arytmetyczny. Tak wydajne jest wdrożenie C, że nawet nie przejmuje się specjalistyczną odwróconą funkcją plasterków i nadal bije realizację czystego Pythona. Raczej tworzy kopię plasterka i odwrócenia plasterka na miejscu (wykonane inaczej gdzie).
Lista Kod plasterka dla Cysthon:
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;
}
Demontaż dla 3 różnych wersji - (bez zrzutów ekranu):
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
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.