Lazy sequence è un involucro speciale su una collezione che consente di ritardare l'esecuzione dei calcoli (filter, map, ecc.) fino al momento dell'accesso diretto agli elementi. Ciò significa che le operazioni su una lazy sequence verranno calcolate solo quando il loro risultato verrà richiesto (ad esempio, durante la chiamata a .forEach, .first, conversione in un array, ecc.).
Quando usare:
Esempio:
let numbers = Array(1...1_000_000) let lazyNumbers = numbers.lazy.map { $0 * 2 }.filter { $0 % 3 == 0 } let first = lazyNumbers.first // Solo adesso verrà calcolata la catena di operazioni per il primo elemento adatto!
Insidie:
Qual è la differenza tra la chiamata
.map { ... }e.lazy.map { ... }su un array?
Risposta:
.map { ... } applica il closure a ciascun elemento e restituisce immediatamente un nuovo array, quindi tutti gli elementi saranno elaborati e memorizzati in memoria..lazy.map { ... } restituisce non un array, ma una lazy-sequence (involucro), che non esegue l'elaborazione degli elementi immediatamente, ma solo quando vi si accede.Esempio:
let a = Array(1...10) let eagers = a.map { $0 * 2 } // Array con 10 elementi let laziers = a.lazy.map { $0 * 2 } // LazySequence, che non contiene immediatamente risultati
Storia
In un grande progetto, uno sviluppatore ha applicato una catena di più chiamate map, filter, reduce a un enorme array di dati senza .lazy. Ciò ha portato all'allocazione temporanea di grandi array ad ogni passaggio intermedio, raddoppiando il consumo di memoria e causando crash su alcuni dispositivi con poca RAM.
Storia
In un blocco di codice è stata utilizzata una lazy sequence con un effetto collaterale nel closure interno (ad esempio, inviare un evento o stampare all'interno di map/filter). Lo sviluppatore si aspettava che questa operazione venisse eseguita immediatamente, tuttavia l'evento non è mai accaduto — perché gli elementi della lazy sequence non sono stati mai acceduti e il codice con l'evento non è stato mai eseguito. Di conseguenza, i log e le metriche sono risultati errati.
Storia
Nel caso della raccolta di statistiche dai dati di un grande database, è stata utilizzata una lazy sequence in combinazione con più passaggi (ad esempio, si cercava due volte il primo elemento, poi si contava). Ogni passaggio attraverso la lazy sequence ha innescato un completo ricalcolo delle operazioni — ciò ha portato a un rallentamento del doppio e a un carico non necessario sul sistema. Dopo la sostituzione con un array normale, il problema è scomparso.