To zawsze mi przeszkadzało. zwłaszcza gdy mój profiler powiedział mi, że spędziłem 2,2 sekundy programu, który działał przez minutę, wywołując tę funkcję.
Nathan,
Odpowiedzi:
87
Nie martw się: oczywiście oszczędza liczbę, a zatem len()na listach jest to dość tania operacja. Nawiasem mówiąc, to samo dotyczy ciągów znaków, słowników i zestawów!
Wydaje mi się, że utrzymuje liczbę, taką jak indeks ostatniej pozycji + 1 lub coś w tym stylu, i wywołuje wartość len () z tego miejsca w pamięci. Czy mam rację?
Napisz swój program tak, aby był zoptymalizowany pod kątem przejrzystości i łatwy w utrzymaniu . Czy Twój program jest bardziej przejrzysty dzięki wezwaniu do len(foo)? Więc zrób to.
Podobnie jak większość ludzi, najprawdopodobniej błędnie zgadniesz, które części programu są najwolniejsze. Unikaj pokusy zgadywania i zamiast tego zmierz ją, aby się dowiedzieć.
Pamiętaj, że przedwczesna optymalizacja jest źródłem wszelkiego zła , jak mówi Donald Knuth. Skoncentruj się tylko na szybkości kodu, którą zmierzyłeś , aby wiedzieć, czy korzyść byłaby warta kosztu zmiany sposobu działania.
Jestem programistą zaledwie kilka miesięcy po mojej pracy i popieram obie praktyki. Stoper oferuje dwuliniową obronę przed dużą liczbą konwencjonalnych mądrości („WYBIERZ .. LOSOWO jest zbyt kosztowna”), która zostanie rzucona w Twoją stronę.
Jesvin Jose
5
Na pytanie udzielono odpowiedzi ( lenjest O (1)), ale oto jak możesz to sprawdzić samodzielnie:
$ python -m timeit -s "l = range(10)""len(l)"10000000 loops, best of 3: 0.119 usec per loop
$ python -m timeit -s "l = range(1000000)""len(l)"10000000 loops, best of 3: 0.131 usec per loop
Ostrzegamy, że niekoniecznie jest to prawdą w każdym języku. Niektóre języki używają listy połączonej i mogą, ale nie muszą, przechowywać metadane dotyczące rozmiaru. Doskonałym przykładem jest Lisp, w którym listy używają stosunkowo prymitywnych struktur 2-komórkowych do budowania się, bez metadanych. W takich przypadkach połączenie o długości zajmuje O (n) czasu.
Odpowiedzi:
Nie martw się: oczywiście oszczędza liczbę, a zatem
len()
na listach jest to dość tania operacja. Nawiasem mówiąc, to samo dotyczy ciągów znaków, słowników i zestawów!źródło
I jeszcze jeden sposób, aby dowiedzieć się, jak to się robi
aby znaleźć to w Google Code Searchspójrz na źródło na GitHub , jeśli nie chcesz samodzielnie pobierać źródła.static Py_ssize_t list_length(PyListObject *a) { return a->ob_size; }
źródło
len
jest operacją O (1) .źródło
Napisz swój program tak, aby był zoptymalizowany pod kątem przejrzystości i łatwy w utrzymaniu . Czy Twój program jest bardziej przejrzysty dzięki wezwaniu do
len(foo)
? Więc zrób to.Martwisz się o czas? Skorzystaj z
timeit
modułu w bibliotece standardowej, aby zmierzyć wymagany czas i sprawdzić, czy jest on istotny w Twoim kodzie.Podobnie jak większość ludzi, najprawdopodobniej błędnie zgadniesz, które części programu są najwolniejsze. Unikaj pokusy zgadywania i zamiast tego zmierz ją, aby się dowiedzieć.
Pamiętaj, że przedwczesna optymalizacja jest źródłem wszelkiego zła , jak mówi Donald Knuth. Skoncentruj się tylko na szybkości kodu, którą zmierzyłeś , aby wiedzieć, czy korzyść byłaby warta kosztu zmiany sposobu działania.
źródło
Na pytanie udzielono odpowiedzi (
len
jest O (1)), ale oto jak możesz to sprawdzić samodzielnie:$ python -m timeit -s "l = range(10)" "len(l)" 10000000 loops, best of 3: 0.119 usec per loop $ python -m timeit -s "l = range(1000000)" "len(l)" 10000000 loops, best of 3: 0.131 usec per loop
Tak, niezbyt wolniej.
źródło
„Lista” w Pythonie jest w rzeczywistości tablicą o zmiennym rozmiarze, a nie listą połączoną, więc gdzieś przechowuje rozmiar.
źródło
Musi gdzieś przechowywać długość, więc nie liczysz za każdym razem liczby elementów.
źródło