wake-up-neo.com

Stream vs Views vs Iteratoren

Was sind die Unterschiede zwischen Streams, Views (SeqView) und Iteratoren in Scala? Das ist mein Verständnis:

  • Das sind alles faule Listen.
  • Streams speichern die Werte im Cache.
  • Iteratoren können nur einmal verwendet werden? Sie können nicht zum Anfang zurückkehren und den Wert erneut auswerten?
  • Die Werte der Ansicht werden nicht zwischengespeichert, aber Sie können sie immer wieder auswerten.

Wenn ich also Heapspeicherplatz sparen möchte, sollte ich Iteratoren (wenn ich die Liste nicht erneut durchquere) oder Ansichten verwenden? Vielen Dank.

131
JWC

Erstens sind sie alle nicht streng. Dies hat eine bestimmte mathematische Bedeutung in Bezug auf Funktionen, bedeutet jedoch im Grunde, dass sie auf Anforderung anstatt im Voraus berechnet werden.

Stream ist in der Tat eine faule Liste. Tatsächlich ist in Scala ein Stream ein List, dessen tail ein lazy val. Einmal berechnet, bleibt ein Wert berechnet und wird wiederverwendet. Oder, wie Sie sagen, die Werte werden zwischengespeichert.

Ein Iterator kann nur einmal verwendet werden, da es sich um einen Traversal-Zeiger in einer Sammlung und nicht um eine Sammlung an sich handelt. Das Besondere an Scala ist die Tatsache, dass Sie Transformationen wie map und filter anwenden und einfach eine neue Iterator erhalten können Wendet diese Transformationen nur an, wenn Sie nach dem nächsten Element fragen.

Scala stellte früher Iteratoren zur Verfügung, die zurückgesetzt werden konnten, die aber im Allgemeinen nur sehr schwer zu unterstützen sind, und die Version 2.8.0 wurde nicht erstellt.

Ansichten sind so zu verstehen, dass sie einer Datenbankansicht ähneln. Es ist eine Reihe von Transformationen, die man auf eine Sammlung anwendet, um eine "virtuelle" Sammlung zu erzeugen. Wie Sie bereits sagten, werden alle Transformationen jedes Mal neu angewendet, wenn Sie Elemente daraus abrufen müssen.

Sowohl Iterator als auch Ansichten weisen hervorragende Speichereigenschaften auf. Stream ist Nice, aber in Scala besteht der Hauptvorteil darin, unendliche Folgen zu schreiben (insbesondere rekursiv definierte Folgen). Eins kann Vermeiden Sie es jedoch, den gesamten Stream im Speicher zu behalten, indem Sie sicherstellen, dass Sie keinen Verweis auf den head behalten (z. B. durch Verwendung von def anstelle von val zur Definition von Stream).

Aufgrund der Nachteile von Ansichten sollte diese normalerweise nach dem Anwenden der Transformationen force oder als Ansicht beibehalten werden, wenn im Vergleich zur Gesamtgröße der Ansicht nur wenige Elemente abgerufen werden sollen.

178