Unerwartetes Speicherwachstum mit Control.Monad foldM

9

Ich habe den folgenden Code, der abgespeckt wurde und ich denke, dass er so minimal wie möglich ist, was sehr merkwürdig ist.

Der Code besteht aus zwei Quelldateien: Eine, um einige Daten zu definieren:

%Vor%

Und der andere ist Main:

%Vor%

Der Code wie oben (kompiliert mit GHC 7.10.3 mit Stack 1.0.0 mit Standard-Flags) hat einen schnellen Anstieg der Speicherauslastung (über 1 GB) und dauert typischerweise 3,3 Sekunden.

Wenn ich den Code ändere, zum Beispiel:

  • Verwenden Sie eine der kommentierten Alternativen zur Problemzeile
  • Entferne eine Zeile aus runFunction

Die Speichernutzung bleibt minimal und dauert nur etwa 1 Sekunde.

Eine Funktion, von der ich denke, dass sie mich am meisten überrascht, ist, dass das Ersetzen von foldM durch foldlM (was soviel ich weiß foldM = foldlM ) das Problem behebt.

Auch Änderungen an Code, die ich nicht sehe, hat irgendeine Beziehung zu den Problemzeilen des Codes, behebt das Problem auch. Zum Beispiel Entfernen der letzten putStrLn.

Eine weitere Kuriosität ist, dass, wenn ich das MyFunction-Modul in das Main-Modul einfüge, das Problem jedoch nicht löst, bewirkt es foldlM , sich als foldM zu verhalten, indem exzessiver Speicher verwendet wird.

In dem echten Code, von dem das kam, habe ich eine große Anzahl exampleFunction s, und es gibt signifikant mehr Main code, und manchmal stoße ich auf diese Art von unerklärter Speicherauslastung von Funktionen, die normalerweise durch eine Art Voodoo gelöst werden.

Ich suche nach einer Erklärung für das Verhalten. Wenn ich weiß, warum das passiert, kann ich dann versuchen, es zu vermeiden. Könnte das ein Compiler-Problem sein, oder vielleicht nur ein Missverständnis von mir?

(*) Ich habe das sekundäre Problem hervorgehoben, das dazu führt, dass bei fulllM das gleiche Speicherwachstum auftritt.

    
pticawr 16.01.2016, 19:01
quelle

1 Antwort

3

Hier ist foldlM von Foldable.hs (ghc)

%Vor%

und foldM von Monad.hs

%Vor%

Ich habe diese Definitionen in einem separaten Modul Test platziert und die Ausführung mit und ohne INLINEABLE / SPESIALISE Zeilen getestet. Was auch immer der Grund ist, die SPECIALIZE-Direktiven weggelassen zu haben, und die Ausführungszeit und Speicherbelegung war wie bei fulllM.

Nach ein wenig mehr Graben, Linie entfernen

%Vor%

hat am meisten bewirkt.

    
J.J. Hakala 17.01.2016 07:48
quelle

Tags und Links