我正在瀏覽Functional Systems in Haskell的幻燈片。在講座中,存在使用unsafeInterleaveIO
列出目錄中的遞歸的所有文件中定義recDir2
功能:cs240:recDir在兩種類似情況下使用的額外150 MB
import qualified Data.ByteString.Lazy as L
recDir2 :: FilePath -> IO [FilePath]
recDir2 dir = do
ds <- openDirStream dir
let protect m = m `onException` closeDirStream ds
nextName = unsafeInterleaveIO $
protect (readDirStream ds) >>= checkName
checkName "" = closeDirStream ds >> return []
checkName "." = nextName
checkName ".." = nextName
checkName name = getSymbolicLinkStatus path >>= checkStat path
where path = dir </> name
checkStat path stat
| isRegularFile stat = liftM (path :) nextName
| isDirectory stat =
liftM2 (++) (protect $ recDir2 path) nextName
| otherwise = nextName
nextName
凡
readFiles :: [FilePath] -> IO L.ByteString
readFiles [] = return L.empty
readFiles (f:fs) = liftM2 L.append (L.readFile f)
(unsafeInterleaveIO $ readFiles fs)
此功能在兩個看似相同的情況後使用:
*Main> recDir2 "/usr/include" >>= readFiles >>= print . L.length
*Main> x <- recDir2 "/usr/include" >>= readFiles
*Main> L.length x
但是在幻燈片中指出,第二種情況使用額外的150 MB,但我沒有看到原因。什麼導致這種據稱額外的內存使用?
我的猜測是:後者無法垃圾收集'x',因爲它被消耗掉了。什麼是'L'和'readFiles'?在不知道代碼的情況下可靠地檢查這種猜測是很難的。 –
我添加了'L'和'readFiles'的定義。在第二種情況下,有什麼收集?由於'readFiles'中的列表是根據需要構建的...... –