/ / F # Speicherverwaltung - Arrays, Speicherverwaltung, Referenz, f #

F # Speicherverwaltung - Arrays, Speicherverwaltung, Referenz, f #

In F #, wenn Sie ein Array in einer Schleife übergeben (rekursivFunktion ruft sich selbst) ist das Array auf dem Stapel (Hinzufügen von Speicherverbrauch) jede Schleife? Wie funktioniert es mit Listen oder referenzierten Objekten beim Schleifen? Könnten Sie den Speicherverbrauch irgendwie minimieren, vielleicht indem Sie ref (Referenzen) verwenden?

Antworten:

1 für die Antwort № 1

Arrays sind Referenztypen, sodass Sie keine Arrays kopieren oder konstruieren, wenn Sie sie als Argumente übergeben. Wenn Sie Arrays in einer rekursiven Funktion übergeben, entsteht kein Platz-Overhead.

Beispielsweise:

let rec loop a i =
if 0 <= i && i < Array.length a then
loop a (a.[i])
else
a.[i]

Diese Funktion springt um das Array herum, bis es einen Wert findet, der kein Index des Arrays ist. Unter der Annahme einer Tail-Call-Optimierung hat es keinen Platz-Overhead, dh es weist nichts zu.


2 für die Antwort № 2

Wenn Sie tail-rekursive Funktionen schreiben, führt F # eine Tail-Call-Optimierung durch, so dass der Stack bei jedem rekursiven Aufruf nicht wächst.

Wenn Sie eine Funktion haben, die nicht tail-rekursiv ist, können Sie etwas verwenden, das als Fortsetzungs-Übergabestil bezeichnet wird, und den Heap anstelle des Stapels verwenden, um Zwischenwerte zu akkumulieren.


1 für die Antwort № 3

Solange Ihre Funktion tail rekursiv ist, müssen Sie sich keine Sorgen machen. Das bedeutet einfach, dass die letzte Funktion Ihrer Funktion sich selbst aufruft. Beispiel:

let rec fact x =
if x < 1 then 1
else x * fact (x - 1)

Diese Funktion multipliziert "s mit x nach fact (x - 1), so dass ihr NOT-Tail rekursiv ist.