2017-02-20 1 views
2

Je voulais tester l'utilisation de la mémoire d'un petit programme de test. Le programme se présente comme suit:Profil de mémoire vide

import Data.List as L 
main :: IO 
main = print $ L.find (==100000) [1..1000000000] 

Il trouve la 100000e valeur. Je m'attendais à voir que ce programme n'utiliserait que la mémoire pour 100000 valeurs. Quand j'ai généré un profil de mémoire via +RTS -hy j'ai un profil vide: enter image description here J'ai été surpris et j'ai pensé que GHC peut être plus efficace que je ne le pensais. Peut-être que les valeurs n'ont jamais dû être chargées en mémoire puisque le résultat peut déjà être déterminé.

J'ai donc expérimenté un problème qui nécessite toutes les valeurs jusqu'à la 100000e:

main = print $ takeUntil (==100000) [1..] 

takeUntil :: (Int -> Bool) -> [Int] -> [Int] 
takeUntil _ [] = [] 
takeUntil f (x:xs) = if f x 
         then [] 
         else x : takeUntil f xs 

encore, le profil de mémoire est vide. Je pensais que c'était parce que GHC effectue une sorte de fusion sur ce programme dans lequel les valeurs sont calculées par takeUntil et imprimées en même temps afin qu'elles puissent être instantanément collectées.

J'ai donc écrit un autre programme qui exige le résultat de takeUntil rester en mémoire:

main = let taken = takeUntil (==100000) [1..] 
      mapped = L.map (+1) taken 
     in print taken >> print mapped 

Cela donne le profil de mémoire que je me attendais: enter image description here Je voulais voir ce que la mémoire du programme utiliserait si J'ai demandé seulement la moitié des échantillons:

main = let taken = takeUntil (==50000) [1..] 
      mapped = L.map (+1) taken 
     in print taken >> print mapped 

J'ai généré le profil de mémoire et encore une fois c'est vide!

Lorsque je demande plus d'échantillons:

main = let taken = takeUntil (==200000) [1..] 
      mapped = L.map (+1) taken 
     in print taken >> print mapped 

Le profil de mémoire est que j'attendre: enter image description here

Quelqu'un peut-il expliquer ce comportement?

Le code se trouve dans un fichier appelé Main.hs. Je compiler via ghc Main.hs -O2 -rtsopts -prof. Je construis le profil de la mémoire en cours d'exécution avec +RTS -hy et générer un pdf en utilisant hp2ps -e8in -c et ps2pdf.

+3

La fréquence de profil de tas par défaut est de 0,1 s, donc vos profils vides sont peut-être simplement parce que le programme n'a pas fonctionné assez longtemps. Vous pouvez ajuster la fréquence du profil de segment avec l'option RTS '-i '. –

+0

@ReidBarton Merci, c'est tout! – Valerie94

+0

@ReidBarton Cela devrait être une réponse. – jkeuhlen

Répondre

3

La fréquence par défaut du profil de segment est de 0,1 s, donc si votre programme ne s'exécute pas assez longtemps, vous obtenez un profil de tas vide. Vous pouvez ajuster la fréquence du profil de segment avec l'option RTS -i<sec>.