Die kurze Antwort:
Nr Die gesamte Liste nicht kopiert wird, nur der Verweis auf sie ist.
Die lange Antwort:
In F # (wie gerade in C#) sowohl Wert und Referenztypen können entweder als Wert oder als Referenz übergeben werden.
Sowohl Werttypen als auch Referenztypen werden standardmäßig als Wert übergeben.
Im Fall von Werttypen (structs) bedeutet dies, dass Sie um eine Kopie der gesamten Datenstruktur vorbei sein werden.
Bei Referenztypen (Klassen, diskriminierte Verschaltungen, Aufzeichnungen usw.) bedeutet dies, dass die Referenz als Wert übergeben wird. Dies bedeutet nicht, dass die gesamte Datenstruktur kopiert wird, sondern lediglich dass ein int
/int64
Verweis auf die Datenstruktur kopiert wird.
Wenn Sie mit veränderbaren Datenstrukturen arbeiten, z. ResizeArray<'T>
(. NET List<'T>
), die Klassen sind, die Weitergabe von Referenzen nach Wert könnte Auswirkungen haben. Vielleicht fügt die Funktion, an die Sie sie übergeben haben, Elemente zur Liste hinzu? Eine solche Aktualisierung würde für die Datenstruktur gelten, auf die von beiden Standorten verwiesen wird. Da Ihre Frage jedoch die unveränderliche F # -Liste verwendet, müssen Sie sich darüber keine Gedanken machen!
Sie können auch Wert/Referenztypen Bezug genommen wird, für weitere Details sehen, dass passieren: https://msdn.microsoft.com/en-us/library/dd233213.aspx#Anchor_4
F # Liste wird als einfach verkettete Liste implementiert, dass Mittel, die den Kopf und prepend Operationen O Zugriff (1). Diese Datenstrukturen sind auch sehr speichereffizient, denn wenn Sie ein Element der Liste voranstellen, müssen Sie nur den neuen Wert und einen Verweis auf den Rest der Liste speichern.
Sie können also sehen, wie es funktioniert, wie eine Datenstruktur, wie diese umgesetzt werden kann:
type ExampleList<'T> =
|Empty
|Cons of 'T * List<'T>
Weitere Informationen:
List.map
eifrig Sinn ausgewertet wird, dass jedes Mal, wenn Sie es nennen, Eine neue Liste wird erstellt. Wenn Sie Seq.map
verwenden (F # List implementiert die Schnittstelle IEnumerable<'T>
), die faul ausgewertet wird, können Sie beide Zuordnungsoperationen nur in der Aufzählung der Liste auswerten.
largeList
|> Seq.map (fun elem -> f elem)
|> Seq.map (fun elem -> f2 elem)
|> List.ofSeq
Dies ist wahrscheinlich viel effizienter für große Listen sein, weil es handelt sich nur um eine neue Liste der Ergebnisse Zuteilung, anstatt zwei.
Strukturen werden nach Wert übergeben, Klassen nach Referenz bar2 kann geringfügig schneller sein, aber der Unterschied wäre sehr klein - einfach messen –
https://ericlippert.com/2012/12/17/performance-rant –