Lazy sequence ist eine spezielle Hülle um eine Sammlung, die es ermöglicht, die Durchführung von Berechnungen (filter, map usw.) bis zum Zeitpunkt des tatsächlichen Zugriffs auf die Elemente zu verzögern. Das bedeutet, dass die Operationen über lazy sequence nur dann berechnet werden, wenn auf ihr Ergebnis zugegriffen wird (zum Beispiel bei einem Aufruf von .forEach, .first, der Umwandlung in ein Array usw.).
Wann man es verwenden sollte:
Beispiel:
let numbers = Array(1...1_000_000) let lazyNumbers = numbers.lazy.map { $0 * 2 }.filter { $0 % 3 == 0 } let first = lazyNumbers.first // Nur jetzt wird die Kette von Operationen für das erste passende Element berechnet!
Fallstricke:
Was ist der Unterschied zwischen dem Aufruf von
.map { ... }und.lazy.map { ... }auf einem Array?
Antwort:
.map { ... } wendet den Closure auf jedes Element an und gibt sofort ein neues Array zurück, d.h. alle Elemente werden verarbeitet und im Speicher gespeichert..lazy.map { ... } gibt kein Array zurück, sondern eine lazy-sequence (Hülle), die die Verarbeitung der Elemente nicht sofort ausführt, sondern nur beim Zugriff auf sie.Beispiel:
let a = Array(1...10) let eagers = a.map { $0 * 2 } // Array mit 10 Elementen let laziers = a.lazy.map { $0 * 2 } // LazySequence, die keine Ergebnisse sofort enthält
Geschichte
In einem großen Projekt wendete ein Entwickler eine Kette mehrerer Aufrufe von map, filter, reduce auf ein riesiges Array von Daten an, ohne .lazy. Das führte zu temporären Allokationen großer Arrays bei jedem Zwischenschritt, verdoppelte den Speicherverbrauch und verursachte Abstürze auf einigen Geräten mit niedrigem RAM.
Geschichte
Im Codeblock wurde eine lazy sequence mit Nebenwirkungen im inneren Closure verwendet (z. B. send event oder print innerhalb von map/filter). Der Entwickler erwartete, dass diese Operation sofort ausgeführt wird, jedoch passierte das Ereignis überhaupt nicht - weil auf die Elemente der lazy sequence nie zugegriffen wurde und der Code mit dem Ereignis gar nicht aufgerufen wurde. In der Folge waren die Protokolle und Metriken unkorrekt.
Geschichte
Bei der Erhebung von Statistiken über Daten aus einer großen Datenbank wurde eine lazy sequence in Kombination mit mehreren Durchgängen verwendet (z. B. einmal wurde first gesucht und dann die count berechnet). Jeder Durchgang durch die lazy sequence initiierte eine vollständige Neuberechnung der Operationen - was zu einer Verdopplung der Verzögerung und unnötiger Belastung des Systems führte. Nach dem Austausch gegen ein gewöhnliches Array verschwand das Problem.