Lazy sequence to specjalny wrapper nad kolekcją, który pozwala opóźnić wykonanie obliczeń (filter, map itd.) do momentu bezpośredniego dostępu do elementów. Oznacza to, że operacje wykonane na lazy sequence będą obliczane tylko wtedy, gdy zostaną z nich odwołane (na przykład przy wywołaniu .forEach, .first, przekształceniu na tablicę itd.).
Kiedy używać:
Przykład:
let numbers = Array(1...1_000_000) let lazyNumbers = numbers.lazy.map { $0 * 2 }.filter { $0 % 3 == 0 } let first = lazyNumbers.first // Dopiero teraz obliczy się łańcuch operacji dla pierwszego odpowiedniego elementu!
Pułapki:
Czym różni się wywołanie
.map { ... }od.lazy.map { ... }na tablicy?
Odpowiedź:
.map { ... } stosuje closure do każdego elementu i od razu zwraca nową tablicę, co oznacza, że wszystkie elementy są przetwarzane i zachowywane w pamięci..lazy.map { ... } zwraca nie tablicę, a lazy-sequence (wrapper), który nie wykonuje przetwarzania elementów od razu, a dopiero przy dostępie do nich.Przykład:
let a = Array(1...10) let eagers = a.map { $0 * 2 } // Tablica z 10 elementami let laziers = a.lazy.map { $0 * 2 } // LazySequence, która nie zawiera wyników od razu
Historia
W dużym projekcie programista zastosował łańcuch kilku wywołań map, filter, reduce na ogromnej tablicy danych bez .lazy. Doprowadziło to do tymczasowego alokowania dużych tablic na każdym pośrednim kroku, zwiększyło zużycie pamięci prawie dwukrotnie i spowodowało awarie na niektórych urządzeniach z niską ilością RAM.
Historia
W bloku kodu użyto lazy sequence z efektem ubocznym w wewnętrznym zamknięciu (na przykład, wysyłanie zdarzenia lub wydruk w map/filter). Programista oczekiwał, że ta operacja zostanie wykonana natychmiast, jednak zdarzenie w ogóle się nie wydarzyło — ponieważ do elementów lazy sequence nigdy nie odwołano się, a kod z zdarzeniem w ogóle nie został wywołany. W rezultacie logi i metryki okazały się niepoprawne.
Historia
W przypadku gromadzenia statystyk z danych z dużej bazy użyto lazy sequence w połączeniu z kilkoma przejściami (na przykład, dwukrotnie szukano first, a potem liczono count). Każde przejście przez lazy sequence inicjowało pełne przeliczenie operacji — co doprowadziło do dwukrotnego spowolnienia i niepotrzebnego obciążenia systemu. Po zastąpieniu tym zwykłą tablicą problem zniknął.