Kompromisy między leniwym a zachłannym wykonaniem
Rozpoznawanie, kiedy leniwe wykonanie pomaga, a kiedy szkodzi.
Kompromisy między leniwym a zachłannym wykonaniem to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Nie ma darmowych obiadów
Leniwe przetwarzanie nie zawsze jest szybsze. Zamienia początkową alokację na narzut przy każdym dostępie i zmienia moment wykonywania efektów ubocznych. Znajomość tych kompromisów pozwala dokonać właściwego wyboru.
Leniwe przetwarzanie wygrywa: częściowe wykorzystanie
Potrzebny jest tylko fragment ogromnej transformacji — leniwe przetwarzanie pomija resztę:
let data = Array(1...1_000_000)
let top = data.lazy.map { $0 * 2 }.prefix(3)
print(Array(top)) // [2, 4, 6] -- 999,997 transforms skippedZachłanne przetwarzanie wygrywa: pełne ponowne użycie
Jeśli iteruje Pan/Pani po wyniku wiele razy, zachłanne przetwarzanie oblicza go raz, a leniwe oblicza ponownie przy każdym przejściu:
let doubled = [1, 2, 3].map { $0 * 2 } // computed once
print(doubled.reduce(0, +)) // 12
print(doubled.max()!) // 6 -- no recomputeLeniwe przetwarzanie oblicza ponownie
Ten sam leniwy widok wykonuje pracę ponownie przy każdej iteracji:
var work = 0
let view = [1, 2, 3].lazy.map { (n: Int) -> Int in work += 1; return n }
_ = view.reduce(0, +)
_ = view.max()
print(work) // 6 -- transformed twiceNarzut dla każdego elementu
Każdy leniwy etap opakowuje sekwencję w kolejny typ i wywołuje domknięcia dla poszczególnych elementów. W przypadku małych tablic ten narzut może przewyższyć korzyść z pominięcia alokacji.
Mała tablica: zachłanne przetwarzanie wystarczy
W przypadku kilku elementów, które są w całości wykorzystywane, należy wybrać zwykłe zachłanne przetwarzanie — jest prostsze, a alokacja ma znikomy koszt:
let nums = [3, 1, 2]
let sorted = nums.map { $0 + 1 }.sorted()
print(sorted) // [2, 3, 4]Moment efektów ubocznych jest inny
W przypadku leniwego przetwarzania ciało domknięcia jest wykonywane później niż wiersz, w którym je zdefiniowano. Należy unikać polegania na efektach ubocznych wewnątrz leniwych transformacji:
var log: [Int] = []
let v = [1, 2].lazy.map { (n: Int) -> Int in log.append(n); return n }
print(log) // [] -- nothing ran yet
_ = Array(v)
print(log) // [1, 2]Operacje wymuszające zachłanne przetwarzanie
Niektóre operacje i tak muszą odczytać całą sekwencję, więc leniwe przetwarzanie nie daje w ich przypadku żadnej korzyści:
let nums = Array(1...10)
print(nums.lazy.map { $0 * 2 }.sorted()) // sorted must see all -> [2,4,...,20]
print(nums.lazy.map { $0 }.count) // count walks everythingLeniwe przetwarzanie i contains
Operacje z krótkim spięciem, takie jak contains(where:), korzystają z leniwego przetwarzania w przypadku dużych danych wejściowych:
let big = Array(1...1_000_000)
let found = big.lazy.map { $0 * 2 }.contains { $0 == 8 }
print(found) // true -- stops at element 4Lista kontrolna wyboru
Należy użyć leniwego przetwarzania, gdy: źródło jest duże ORAZ zachowuje Pan/Pani tylko jego część (prefix / first / contains) ORAZ iteruje Pan/Pani po nim raz. Należy użyć zachłannego przetwarzania, gdy: tablica jest mała, wynik będzie ponownie używany lub czytelność jest ważniejsza niż mikrooptymalizacja.
let huge = Array(1...100_000)
let first = huge.lazy.filter { $0 % 9973 == 0 }.first
print(first!) // 9973Należy mierzyć, a nie zgadywać
Intuicja dotycząca wydajności często zawodzi. Gdy ma to znaczenie, należy porównać obie wersje na realistycznych danych przed wybraniem leniwego przetwarzania.
let nums = Array(1...50)
let eager = nums.filter { $0 > 25 }.count
let lazyC = nums.lazy.filter { $0 > 25 }.count
print(eager == lazyC) // true -- same answer, profile for speedSzybkie sprawdzenie
Kiedy zachłanne przetwarzanie jest lepszym wyborem niż leniwe?
Podsumowanie
Poznał(a) Pan/Pani kompromisy:
- Leniwe przetwarzanie wygrywa w przypadku dużych źródeł, częściowego wykorzystania w jednym przejściu
- Zachłanne przetwarzanie wygrywa w przypadku małych tablic i ponownie używanych wyników (leniwe oblicza wynik ponownie)
- Efekty uboczne w leniwych transformacjach są wykonywane później — należy unikać polegania na nich
- Przed optymalizacją należy wykonać pomiary
Dalej: tworzenie niestandardowych leniwych sekwencji.
Często zadawane pytania
Czy lekcja „Kompromisy między leniwym a zachłannym wykonaniem” jest bezpłatna?
Tak — pełny tekst „Kompromisy między leniwym a zachłannym wykonaniem” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Kompromisy między leniwym a zachłannym wykonaniem”?
Rozpoznawanie, kiedy leniwe wykonanie pomaga, a kiedy szkodzi. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Kompromisy między leniwym a zachłannym wykonaniem”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Właściwość lazy
- Leniwe map i filter
- Kompromisy między leniwym a zachłannym wykonaniem
- Budowanie niestandardowych sekwencji leniwych