Czy istnieje różnica w wydajności między krotkami i listami, jeśli chodzi o tworzenie instancji i pobieranie elementów?
python
performance
list
tuples
python-internals
Tylko czytać
źródło
źródło
Odpowiedzi:
dis
Moduł demontuje kodu bajtowego dla funkcji i jest przydatna, aby zobaczyć różnicę między krotki i list.W tym przypadku widać, że dostęp do elementu generuje identyczny kod, ale przypisanie krotki jest znacznie szybsze niż przypisanie listy.
źródło
ListLike
z__getitem__
, że robi coś strasznie powolny, a następnie zdemontowaćx = ListLike((1, 2, 3, 4, 5)); y = x[2]
. Kod bajtowy będzie bardziej podobny do powyższego przykładu krotki niż przykładu z listy, ale czy naprawdę wierzysz, że oznacza to, że wydajność będzie podobna?Ogólnie można oczekiwać, że krotki będą nieco szybsze. Jednak zdecydowanie powinieneś przetestować konkretny przypadek (jeśli różnica może wpłynąć na wydajność twojego programu - pamiętaj, że „przedwczesna optymalizacja jest źródłem wszelkiego zła”).
Python sprawia, że jest to bardzo łatwe: timeit jest twoim przyjacielem.
i...
Tak więc w tym przypadku tworzenie krotki jest prawie o rząd wielkości szybsze dla krotki, ale dostęp do przedmiotów jest w rzeczywistości nieco szybszy dla listy! Jeśli więc tworzysz kilka krotek i uzyskujesz do nich dostęp wiele razy, użycie list może być szybsze.
Oczywiście, jeśli chcesz zmienić element, lista będzie zdecydowanie szybsza, ponieważ musisz utworzyć zupełnie nową krotkę, aby zmienić jeden element (ponieważ krotek są niezmienne).
źródło
python -m timeit "x=tuple(xrange(999999))"
kontrapython -m timeit "x=list(xrange(999999))"
. Jak można się spodziewać, zmaterializowanie krotki zajmuje więcej czasu niż listy.-s "SETUP_CODE"
Prowadzony jest przed właściwym kodem czasowym.Podsumowanie
Krotki mają zwykle lepsze wyniki niż listy w prawie każdej kategorii:
1) Krotki można składać na stałe .
2) Krotki można ponownie wykorzystać zamiast kopiować.
3) Krotki są kompaktowe i nie nadmiernie przydzielają.
4) Krotki odnoszą się bezpośrednio do swoich elementów.
Krotki można składać na stałe
Krotki stałych mogą być wstępnie obliczone przez optymalizator wizjera Pythona lub optymalizator AST. Z drugiej strony listy są tworzone od zera:
Krotki nie muszą być kopiowane
Uruchomienie
tuple(some_tuple)
natychmiast wraca. Ponieważ krotki są niezmienne, nie trzeba ich kopiować:Z drugiej strony
list(some_list)
wymaga skopiowania wszystkich danych na nową listę:Krotki nie przydzielają nadmiernie
Ponieważ rozmiar krotki jest stały, może być przechowywany w bardziej zwarty sposób niż listy, które muszą zostać nadmiernie przydzielone, aby operacje append () były wydajne.
Daje to krotkom niezłą przewagę przestrzenną:
Oto komentarz Objects / listobject.c, który wyjaśnia, co robią listy:
Krotki odnoszą się bezpośrednio do ich elementów
Odwołania do obiektów są wbudowane bezpośrednio w krotkę. Natomiast listy mają dodatkową warstwę pośrednią w stosunku do zewnętrznego zestawu wskaźników.
Daje to krotkom niewielką przewagę prędkości podczas indeksowanych wyszukiwań i rozpakowywania:
Oto jak
(10, 20)
przechowywana jest krotka :Oto jak
[10, 20]
przechowywana jest lista :Zauważ, że obiekt krotki zawiera dwa wskaźniki danych bezpośrednio, podczas gdy obiekt listy ma dodatkową warstwę pośrednią względem zewnętrznej tablicy zawierającej dwa wskaźniki danych.
źródło
Internally, tuples are stored a little more efficiently than lists, and also tuples can be accessed slightly faster.
Jak w takim razie mógłbyś wyjaśnić wyniki odpowiedzi dF?tuple(some_tuple)
zwracasome_tuple
się tylko wtedy, gdysome_tuple
jest haszowalny - gdy jego zawartość jest rekurencyjnie niezmienna i haszowalna. W przeciwnym razietuple(some_tuple)
zwraca nową krotkę. Na przykład, gdysome_tuple
zawiera zmienne elementy.Krotki, ponieważ są niezmienne, są bardziej wydajne pod względem pamięci; list, w celu zwiększenia wydajności, ogólnie przydziel pamięć, aby umożliwić dołączanie bez stałych
realloc
s. Tak więc, jeśli chcesz iterować przez stałą sekwencję wartości w swoim kodzie (np.for direction in 'up', 'right', 'down', 'left':
), Krotki są preferowane, ponieważ takie krotki są wstępnie obliczane w czasie kompilacji.Prędkości dostępu powinny być takie same (oba są przechowywane jako ciągłe tablice w pamięci).
Ale
alist.append(item)
jest znacznie bardziej preferowany,atuple+= (item,)
gdy masz do czynienia ze zmiennymi danymi. Pamiętaj, że krotki mają być traktowane jako rekordy bez nazw pól.źródło
Powinieneś również rozważyć
array
moduł w standardowej bibliotece, jeśli wszystkie elementy na liście lub krotce są tego samego typu C. Zajmie mniej pamięci i może być szybszy.źródło
Oto kolejny mały wzorzec, dla samego dobra ..
Uśrednijmy te:
Możesz to nazwać prawie niejednoznaczne.
Ale na pewno krotki zajęły
101.239%
czas lub1.239%
dodatkowy czas na wykonanie zadania w porównaniu do list.źródło
Krotki powinny być nieco bardziej wydajne i dlatego szybsze niż listy, ponieważ są niezmienne.
źródło
Głównym powodem, dla którego Tuple jest bardzo wydajny w czytaniu, jest to, że jest niezmienny.
Dlaczego niezmienne obiekty są łatwe do odczytania?
Powodem jest to, że krotki mogą być przechowywane w pamięci podręcznej, w przeciwieństwie do list. Program zawsze odczytuje z pamięci miejsca listy, ponieważ jest zmienny (można go zmienić w dowolnym momencie).
źródło