Ich fange gerade mit F # an, also sei bitte freundlich, wenn das einfach ist.
Ich habe gelesen, dass eine als faul markierte Funktion nur einmal ausgewertet und dann zwischengespeichert wird. Zum Beispiel:
%Vor%Im Vergleich zu dieser Version, die bei jedem Aufruf tatsächlich ausgeführt wird:
%Vor%Darauf basierend sollten alle Funktionen faul gemacht werden? Wann möchtest du nicht? Dies kommt von Material in dem Buch "Beginning F #" .
Zunächst kann es hilfreich sein, zu beachten, dass keines der von Ihnen definierten Dinge eine Funktion ist - eagerFunc
und theValue
sind Werte vom Typ int
und lazyFunc
ist ein Wert vom Typ Lazy<int>
. Gegeben
und
%Vor% Der Ausdruck 1 + 1
wird nicht mehr als einmal ausgewertet, egal wie oft eagerTwo
verwendet wird. Der Unterschied besteht darin, dass 1 + 1
einmal genau ausgewertet wird, wenn definierend eagerTwo
ist, aber höchstens bewertet wird, wenn lazyTwo
wird verwendet (es wird beim ersten Zugriff auf die Eigenschaft Value
ausgewertet und dann zwischengespeichert, damit die weitere Verwendung von Value
nicht neu berechnet werden muss). Wenn auf lazyTwo
s Value
niemals zugegriffen wird, wird sein Körper 1 + 1
nie ausgewertet.
Normalerweise werden Sie keinen großen Nutzen darin sehen, faule Werte in einer strengen Sprache wie F # zu verwenden. Sie fügen einen geringen Overhead hinzu, da beim Zugriff auf die Eigenschaft Value
überprüft werden muss, ob der Wert bereits berechnet wurde. Sie können Ihnen ein wenig Rechenzeit einsparen, wenn Sie etwas wie let lazyValue = lazy someVeryExpensiveCalculationThatMightNotBeNeeded()
haben, da die teure Berechnung nur stattfindet, wenn der Wert tatsächlich verwendet wird. Sie können auch einige Algorithmen beenden lassen, die es sonst nicht geben würde, aber das ist kein großes Problem in F #. Zum Beispiel:
Wenn Funktionsausführungen Nebeneffekte haben und es wichtig ist, die Nebenwirkungen jedes Mal zu sehen, wenn die Funktion aufgerufen wird (etwa wenn sie eine I / O-Funktion umschließt), sollte sie nicht faul sein.
Es gibt auch Funktionen, die so trivial sind, dass die Ausführung jedes Mal schneller ist als das Zwischenspeichern des Wertes -
let eagerFunc = (1 + 1)
ist eine gebundene Bindung und wird nur einmal ausgeführt. let eagerFunc() = (1 + 1)
ist eine Funktion, die unit
(nichts) akzeptiert und eine int
zurückgibt. Es wird jedes Mal ausgeführt, wenn es aufgerufen wird. In gewisser Hinsicht ist jede Funktion faul, dh sie wird nur ausgeführt, wenn sie aufgerufen wird. Das lazy
-Schlüsselwort (und System.Lazy
, das es zurückgibt) führt jedoch den Ausdruck / die Funktion aus, die ihm höchstens einmal gegeben wurde. Nachfolgende Aufrufe der Eigenschaft Value
geben das zwischengespeicherte Ergebnis zurück. Dies ist nützlich, wenn die Berechnung des Werts teuer ist.
Viele Funktionen sind nicht zur Verwendung mit lazy
geeignet, da sie entweder nicht deterministisch sind (bei jedem Aufruf ein anderes Ergebnis liefern können) oder parametrisiert sind. Natürlich ist es möglich, eine vollständig angewendete Version dieser Funktionen zu verwenden (ein Wert wird für jeden Parameter mitgeliefert), aber im Allgemeinen ist die Variabilität erwünscht.
Tags und Links f# lazy-evaluation