deque.popleft()
i list.pop(0)
wydają się zwracać ten sam wynik. Czy istnieje między nimi różnica w wydajności i dlaczego?deque.popleft() i list.pop (0). Czy jest różnica w wydajności?
Odpowiedz
deque.popleft() jest szybszy niż list.pop (0), ponieważ deque został zoptymalizowany do wykonania popleft() w przybliżeniu w O (1), podczas gdy list.pop (0) pobiera O (n) (patrz deque objects).
Komentarze i kod w _collectionsmodule.c dla deque i listobject.c dla listy zawierają informacje na temat implementacji, aby wyjaśnić różnice w wydajności. Mianowicie, że obiekt deque "składa się z podwójnie połączonej listy", która efektywnie optymalizuje dodatki i wyskakuje na obu końcach, podczas gdy obiekty listy nie są nawet pojedynczymi połączonymi listami, ale tablicami C (wskaźników do elementów (patrz Python 2.7 listobject.h#l22 i Python 3.5 listobject.h#l23) , co czyni je przydatnymi do szybkiego losowego dostępu elementów, ale wymaga czasu (n) na przesunięcie wszystkich elementów po usunięciu pierwszego.
Dla Pythona 2.7 i 3.5, adresy URL tych plików kodu źródłowego są:
https://hg.python.org/cpython/file/2.7/Modules/_collectionsmodule.c
https://hg.python.org/cpython/file/3.5/Modules/_collectionsmodule.c
Używanie% timeit, różnica w wydajności między deque.popleft() i list.pop (0) wynosi około 4, gdy zarówno deque i lista mają te same 52 elementy i rosną do ponad 1000 razy, gdy ich długości to 10 ** 8. Wyniki testu podano poniżej.
import string
from collections import deque
%timeit d = deque(string.letters); d.popleft()
1000000 loops, best of 3: 1.46 µs per loop
%timeit d = deque(string.letters)
1000000 loops, best of 3: 1.4 µs per loop
%timeit l = list(string.letters); l.pop(0)
1000000 loops, best of 3: 1.47 µs per loop
%timeit l = list(string.letters);
1000000 loops, best of 3: 1.22 µs per loop
d = deque(range(100000000))
%timeit d.popleft()
10000000 loops, best of 3: 90.5 ns per loop
l = range(100000000)
%timeit l.pop(0)
10 loops, best of 3: 93.4 ms per loop
Tak, a to znaczące, jeśli masz długą listę lub deque. Wszystkie elementy na liście są umieszczane w pamięci, dlatego jeśli usuniesz dowolny element, wszystkie kolejne elementy muszą zostać przesunięte o jedną pozycję w lewo - dlatego czas wymagany do usunięcia lub wstawienia elementu na początku listy jest proporcjonalny do długość listy. Z drugiej strony, deque jest specjalnie skonstruowany, aby umożliwić szybkie wstawianie lub usuwanie przy końcu (zwykle przez umożliwienie "pustych" miejsc pamięci na początku zakleszczenia, lub zawinięcie wokół, tak aby koniec segmentu pamięci zajmowane przez kapłankę mogą zawierać elementy, które faktycznie są uważane za znajdujące się na początku deque).
porównać skuteczność tych dwóch fragmentów:
d = deque([0] * 1000000)
while d:
d.popleft()
if len(d) % 100 == 0:
print(len(d))
lst = [0] * 1000000
while lst:
lst.pop(0)
if len(lst) % 100 == 0:
print(len(lst))
Czy istnieje różnica wydajności?
Tak. deque.popleft()
jest O(1)
- stała operacja czasowa. Podczas gdy list.pop(0)
jest O(n)
- liniowa operacja czasu: im większa lista, tym dłużej trwa.
Dlaczego?
Implementacja listy CPython opiera się na tablicach. pop(0)
usuwa pierwszy element z listy i wymaga przesunięcia w lewo elementów len(lst) - 1
, aby wypełnić lukę.
Wdrożenie wykorzystuje podwójnie połączoną listę. Bez względu na to, jak duża jest deque, deque.popleft()
wymaga stałej (ograniczonej powyżej) liczby operacji.
@Bin: Wspomniałem tylko o CPythonie, ponieważ nie mogę znaleźć odpowiedniego odnośnika w [spec] (https://docs.python.org/3/reference/) (wygląda na to, że błąd występuje, gdy Python reference doesn nie określaj złożoności czasu dla listy Pythona). Chociaż w praktyce wszystkie implementacje Pythona (które znam) respektują oczekiwaną [nieformalną złożoność czasu dla operacji na listach] (https://wiki.python.org/moin/TimeComplexity). – jfs
https://docs.python.org/2/library/collections.html#collections.deque komentarze na temat złożoności czasu listy dla pop (0) i wstawiania (0, v). –
@TrisNefzger: deque docs express "powszechna wiedza", ale określenie zachowania listy podczas przekazywania wydaje się mniej wiążące niż odniesienie do języka. – jfs
- 1. Różnica między array.GetLength (0) i array.GetUpperBound (0)
- 2. Jaka jest różnica w wydajności między fetchall_hashref i fetchall_arrayref DBI?
- 3. Jaka jest różnica w wydajności między blokami i wywołaniami zwrotnymi?
- 4. Dziwna różnica wydajności C++?
- 5. Jaka jest różnica między [0] a & a [0] w łańcuchu
- 6. Jaka jest różnica między "#if Foo - 0 == 0" i "#if defined (Foo) && Foo == 0"?
- 7. CROSS APPLY różnica wydajności
- 8. Różnica w wydajności dla stanu pętli?
- 9. Android drawBitmap 5x różnica wydajności
- 10. Czy istnieje różnica między int x {}; i int x = 0 ;?
- 11. Jaka jest różnica między {0} a ""?
- 12. Różnica między zakończeniem() i System.exit (0)
- 13. Różnica między licznością "*" i "0 .. *" - UML
- 14. jQuery różnica wydajności bez „każdego”
- 15. Różnica w wydajności między numpy a matlab
- 16. Różnica w wydajności JavaScript między podwójnymi równymi (==) i potrójnymi równymi (===)
- 17. pętla foreach Różnica wydajności listy
- 18. Różnica w wydajności AtomicInteger vs Integer
- 19. Różnica w wydajności między gcc i g ++ dla programu C
- 20. Licznik wydajności ASP.NET zawsze zwraca wartość 0
- 21. Czy to [0] jest bezpieczne w C++?
- 22. Jaka jest różnica między [0] a [: 1] w Go?
- 23. Jak duża jest różnica w wydajności między std :: sort i std :: stable_sort w praktyce?
- 24. Czy jest jakaś różnica w wydajności dla zagnieżdżonego dokumentu w zapytaniu mongodb
- 25. C# - For vs Foreach - Ogromna różnica wydajności
- 26. Jaka jest różnica wydajności pKI do szyfrowania symetrycznego?
- 27. Bluemix, aplikacja push z server.xml vs cały Liberty Server, czy jest różnica w wydajności?
- 28. Co to jest $ (0) i $ (1) używane w jQuery?
- 29. Obiektywna-C, .m/.mm różnica wydajności?
- 30. Jaka jest różnica między "||" operator i funkcja concat w Oracle?
Dzięki. W związku z tym kolejne elementy muszą zostać przesunięte. – Bin
BTW, to samo dotyczy 'deque.appendleft()' vs 'list.insert (0)' –
Bin: Tak. @AndreaCorbellini: Całkiem tak. –