Die Memoisierung ist eine Programmiertechnik, mit der die Leistung von Funktionen durch Zwischenspeicherung ihrer Ergebnisse optimiert wird. In Ruby wird die Memoisierung häufig verwendet, um redundante Berechnungen zu vermeiden und die Effizienz zu verbessern, insbesondere in Situationen, in denen eine Methode mehrfach mit denselben Argumenten aufgerufen wird. Dieser Leitfaden führt Sie durch die Grundlagen der Memoisierung in Ruby und zeigt Ihnen anhand von Beispielen, wie Sie sie implementieren können.
Was ist Memoisierung?
Bei der Memoisierung werden die Ergebnisse teurer Funktionsaufrufe gespeichert und wiederverwendet, wenn die gleichen Eingaben erneut auftreten. Dies kann die Leistung in Szenarien, in denen Berechnungen mit identischen Eingaben wiederholt werden, erheblich beschleunigen.
So funktioniert die Ruby-Memoisierung
Die Memoisierung funktioniert, indem die Ergebnisse von Methodenaufrufen in einer Instanzvariablen zwischengespeichert werden. Wenn die Methode mit denselben Parametern aufgerufen wird, wird das zwischengespeicherte Ergebnis zurückgegeben, anstatt das Ergebnis neu zu berechnen.
Grundlegendes Beispiel
Hier ist ein einfaches Beispiel, um die Memoisierung in Ruby zu veranschaulichen:
class Fibonacci def initialisieren @cache = {} end def fibonacci(n) return n if n <= 1 return @cache[n] if @cache.key?(n) @cache[n] = fibonacci(n - 1) + fibonacci(n - 2) end end fib = Fibonacci.new puts fib.fibonacci(10) # Ausgabe: 55
Erläuterung:
- Wir definieren eine Fibonacci-Klasse mit einer Instanzvariablen @cache, um zuvor berechnete Werte zu speichern.
- Die Fibonacci-Methode prüft, ob das Ergebnis bereits mit @cache.key?(n) zwischengespeichert wurde. Ist dies der Fall, gibt sie das zwischengespeicherte Ergebnis zurück.
- Wenn das Ergebnis nicht zwischengespeichert ist, wird der Wert berechnet und in @cache gespeichert, bevor er zurückgegeben wird.
Memoisierung mit '||=' Operator
Ruby bietet eine Kurzform für die Memoisierung mit dem Operator '||='. Dieser Operator weist einer Variablen nur dann einen Wert zu, wenn die Variable nil oder false ist. Hier sehen Sie, wie Sie ihn für die Memoisierung verwenden können:
class ExpensiveCalculation def initialize(daten) @Daten = Daten end def Ergebnis @result ||= perform_expensive_calculation end privat def perform_expensive_calculation # Simulieren einer teuren Operation sleep(2) @Daten * 2 end end calc = ExpensiveCalculation.new(10) puts calc.result # Benötigt beim ersten Aufruf 2 Sekunden, kehrt dann bei weiteren Aufrufen sofort zurück puts calc.result
Erläuterung:
- Die Methode result verwendet den Operator ||=, um @result das Ergebnis von perform_expensive_calculation nur dann zuzuweisen, wenn @result gleich null ist.
- Bei nachfolgenden Aufrufen von result wird der zwischengespeicherte Wert von @result sofort zurückgegeben, wodurch die teure Berechnung umgangen wird.
Memoisierung mit Blöcken
Die Memoisierung kann auch mit Blöcken verwendet werden. Hier ist ein Beispiel für die Verwendung eines Blocks zum Zwischenspeichern von Ergebnissen:
Klasse Calculator def initialisieren @cache = {} end def memoize(Schlüssel) @cache[Schlüssel] ||= Ertrag end end calc = Rechner.neu Ergebnis = calc.memoize(:Quadrat_von_5) { 5 * 5 } puts result # Ausgabe: 25
Erläuterung:
- Die Methode memoize benötigt einen Schlüssel und einen Block. Sie wertet den Block aus und speichert das Ergebnis, wenn der Schlüssel nicht bereits in @cache vorhanden ist.
- Bei nachfolgenden Aufrufen mit demselben Schlüssel wird das zwischengespeicherte Ergebnis zurückgegeben.
Abschluss
Die Memoisierung ist eine leistungsstarke Technik zur Verbesserung der Leistung in Ruby-Anwendungen durch Vermeidung redundanter Berechnungen. Durch das Zwischenspeichern der Ergebnisse teurer Methodenaufrufe können Sie die Ausführungszeit erheblich reduzieren und die Effizienz verbessern. Ob Sie nun Instanzvariablen, den Operator ||= oder Memoisierung mit Blöcken verwenden, diese Technik kann an verschiedene Szenarien angepasst werden, um Ihren Code zu optimieren.