Ich bin etwas verwirrt darüber, wie der folgende Code ausgeführt wird, wenn er mit GHC 7.6.3 kompiliert wird.
%Vor% Kompiliert mit ghc --make -O3
, bringt es mir folgendes Ergebnis:
Aber wenn ich es in show $ m1 M.! 555
ändere, bekomme ich viel weniger Speicherverbrauch, dauert aber fast gleichzeitig:
Was passiert hier eigentlich? Wird die gesamte Map instanziiert, nur weil ich einen einzelnen Wert ausgelesen habe? Hätte ich das irgendwie verhindern können? Ich meine, es ist ein binärer Suchbaum, also habe ich erwartet, dass nur der eine Pfad, den ich auf der neuen Karte nachgeschlagen habe, tatsächlich evaluiert wird.
Ich glaube, ich habe es verstanden. Schauen wir uns die Quelle für Data.Map.map
an.
Nun scheint mapWithKey
nur den obersten Konstruktor des Baumes zu erstellen und träge für die beiden Zweige zu rekrutieren ... aber:
Oben sehen wir, dass die Teilbäume strikte Felder sind! Daher werden die rekursiven Aufrufe von mapWithKey
erzwungen, was dazu führt, dass der vollständige Baum strikt anstatt langsam aktualisiert wird.
Tags und Links haskell ghc lazy-evaluation