2017-02-08 2 views
3

Mein grundlegendes Verständnis der Linsenbildung is that, "ein Objektiv ist ein Wert, der Karten zwischen einem komplexen Typ und einem seiner Bestandteile darstellt. Diese Karte funktioniert in beide Richtungen - wir können den Bestandteil erhalten und" zugreifen " Setzen oder "mutieren" es "Scala: Lensing vs veränderbares Design

Ich stieß auf diese, als ich eine maschinelle Lernbibliothek (neuronale Netze) entwarf, die erfordert, eine große Datenstruktur von Parametern zu behalten, deren Gruppen in verschiedenen Stadien des Algorithmus aktualisiert werden müssen . Ich wollte die gesamte Parameterdatenstruktur unveränderlich erstellen, aber das Ändern einer einzelnen Parametergruppe erfordert das Kopieren aller Parameter und das Neuerstellen einer neuen Datenstruktur, was sich als ineffizient herausstellt. Nicht überraschend other peoplehave thought es auch. Einige Leute schlagen vor, Linsen zu verwenden, die in gewissem Sinne die Veränderung von unveränderlichen Datenstrukturen ermöglichen. Während andere Leute vorschlugen, nur Mutables für diese zu verwenden. Leider konnte ich nichts über den Vergleich dieser beiden Paradigmen, Geschwindigkeit, Raum, Code-Komplexität usw. finden.

Jetzt ist die Frage, was sind die Vor-/Nachteile der Verwendung von Objektiv vs vs-Design?

Antwort

4

Die Kompromisse zwischen den beiden sind so ziemlich wie Sie vermutet. Objektive sind weniger komplex als das Verfolgen der Änderungen an einer großen unveränderlichen Datenstruktur manuell, erfordern jedoch immer komplexeren Code als eine veränderbare Datenstruktur, und es gibt einen gewissen Zeitaufwand für die Laufzeit. Um zu wissen, wie viel, müssten Sie messen, aber es ist wahrscheinlich weniger als Sie denken, weil viel der aktualisierten Struktur nicht kopiert wird, sondern shared.

Veränderbare Datenstrukturen sind einfacher und etwas schneller zu modifizieren, aber schwieriger zu begründen, weil Sie jetzt die Reihenfolge der Funktionen berücksichtigen müssen, sich Sorgen um Nebenläufigkeit machen und so weiter.

Ihre dritte Option besteht darin, eine Reihe kleiner unveränderlicher Datenstrukturen statt einer großen zu erstellen. Mutabilität erzwingt oft eine einzige große Datenstruktur, weil nur eine einzige Wahrheitsquelle benötigt wird und um sicherzustellen, dass alle Verweise auf Daten sich gleichzeitig ändern. Mit der Unveränderlichkeit ist dies viel einfacher zu kontrollieren.

Zum Beispiel können Sie zwei separate Maps mit der gleichen Art von Schlüssel und verschiedene Arten von einfachen Werten, anstelle von einem Map mit einem komplexeren Wert haben. Dies hat nicht nur Leistungsvorteile, sondern erleichtert auch die Modularisierung Ihres Codes.

+0

Danke für die nette Antwort. Eine Frage jedoch: Warum Objektivieren keine Probleme für Nebenläufigkeit schafft? (Wenn es mit Mutables vergleichbar ist, würde es Sinn ergeben, wenn es die gleichen Probleme mit Parallelität hat) – Daniel

+1

Lensing ist immer noch unveränderlich, es erstellt nur eine API, die einer tiefen Mutation ähnelt. Wenn Sie einen "Satz" machen, hat jeder andere, der einen Verweis auf einen Teil der alten Struktur hat, immer noch den alten unmodifizierten Wert. Sie müssen das Ergebnis einer neuen Variablen in einem neuen Bereich zuweisen. –