Welche Art zu verwenden, zu speichern, eine in-memory-veränderliche Daten-Tabelle in der Scala?
Jedes mal, wenn eine Funktion aufgerufen wird, wenn es für einen gegebenen Satz von argument-Werten ist noch nicht memoized ich möchte das Ergebnis in einer Tabelle im Arbeitsspeicher. Eine Säule gemeint ist, die zum speichern eines Ergebnisses, andere zu speichern Argumente Werte.
Wie kann ich am besten die Umsetzung dieser? Argumente sind von verschiedenen Arten, darunter auch einige enums.
In C# würde ich in der Regel verwenden DataTable. Gibt es ein äquivalent in Scala?
- Wenn Sie das Web für die Suche "Scala-Funktion Memoization" finden Sie verschiedene Behandlungen dieses Themas.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnte man eine
mutable.Map[TupleN[A1, A2, ..., AN], R]
, oder wenn der Speicher ist ein Anliegen, eine WeakHashMap[1]. Die Definitionen unten (gebaut auf der memoization code von michid ' s blog) können Sie einfach memoize Funktionen mit mehreren Argumenten. Zum Beispiel:Definitionen:
Den fixed-point-combinator (
Memoize.Y
) macht es möglich memoize rekursive Funktionen:[1] WeakHashMap funktioniert nicht gut als cache. Sehen http://www.codeinstructions.com/2008/09/weakhashmap-is-not-cache-understanding.html und in diesem Zusammenhang Frage.
yf
ruftyf
, während in der verlinkten wrick Variante, eine memoized hätte, würde die Funktion sich selbst aufrufen.Version vorgeschlagen, die von anovstrup mit einem mutable-Karte ist im Grunde das gleiche wie in C#, und daher einfach zu bedienen.
Aber wenn Sie möchten, können Sie auch eine weitere funktionelle Stil sowie. Es nutzt unveränderlich Karten, die als eine Art accumalator. Mit Tupeln (statt Int im Beispiel) als Schlüssel funktioniert genau wie in der veränderlichen Fall.
Natürlich ist das ein bisschen komplizierter, aber eine sinnvolle Technik, um zu wissen (beachten Sie, dass der obige code soll für Klarheit, nicht für die Geschwindigkeit).
Ein Neuling in diesem Thema, könnte ich voll verstehen keines der Beispiele gegeben (aber danke trotzdem). Bei allem Respekt, ich möchte hier meine Lösung für den Fall, jemand kommt hier mit einem gleichen level und das gleiche problem. Ich denke mein code können Sie crystal clear für jemand mit nur die sehr-sehr grundlegende Kenntnisse in Scala.
Funktioniert perfekt. Würde ich mich über Kritik, Wenn ich was übersehen habe.
Bei der Verwendung veränderlich Karte für memoization, man soll im Hinterkopf behalten, dass dies würde dazu führen, typische concurrency-Probleme, z.B. einen bekommen, wenn ein Schreibvorgang noch nicht beendet ist. Jedoch thread-sicher Versuch von memoization schlägt vor, zu tun, so ist es von wenig Wert, wenn nicht gar keiner.
Folgenden thread-sicheren code erstellt eine memoized
fibonacci
- Funktion, initiiert von ein paar threads (mit dem Namen 'a' bis 'd'), die Anrufe zu es. Versuchen Sie, den code ein paar mal (REPL), kann man leicht sehenf(2) set
wird gedruckt mehr als einmal. Dies bedeutet, den Faden veranlasst hat, die Berechnung derf(2)
aber Thread B hat absolut keine Ahnung davon und startet seine eigene Kopie der Berechnung. Solche Ignoranz ist so allgegenwärtig in der Bau-phase der cache, weil alle threads zu sehen, keine sub-Lösung hergestellt und in dieelse
- Klausel.Neben Landei Antwort, ich möchte auch vorschlagen, die bottom-up - (nicht-memoization) Weise zu tun, DP in Scala möglich ist, und die Kern-Idee ist die Verwendung
foldLeft
(s).Beispiel für die Berechnung Fibonacci-zahlen
Beispiel mit der längsten steigenden Teilfolge