假設我有幾個200mb +的文件需要grep。我如何在Haskell中做到這一點?解析Haskell中的大日誌文件
這裏是我的初步方案:
import Data.List
import Control.Monad
import System.IO
import System.Environment
main = do
filename <- liftM head getArgs
contents <- liftM lines $ readFile filename
putStrLn . unlines . filter (isPrefixOf "import") $ contents
這讀取整個文件到內存中,通過分析它之前。 然後我帶着這樣的:
import Data.List
import Control.Monad
import System.IO
import System.Environment
main = do
filename <- liftM head getArgs
file <- (openFile filename ReadMode)
contents <- liftM lines $ hGetContents file
putStrLn . unlines . filter (isPrefixOf "import") $ contents
我想既然hGetContents
很懶,it will avoid reading the whole file into memory。但是,在valgrind
下運行這兩個腳本都顯示出類似的內存使用情況。所以無論我的腳本是錯誤的,還是valgrind
都是錯誤的。我編譯腳本使用
ghc --make test.hs -prof
我錯過了什麼?獎金問題:我看到很多關於如何在Haskell中使用惰性IO實際上是一件壞事的提及。如何/爲什麼我會使用嚴格的IO?
更新:
所以看起來我錯了,我的valgrind的讀數。使用+RTS -s
,這裏就是我得到:
7,807,461,968 bytes allocated in the heap
1,563,351,416 bytes copied during GC
101,888 bytes maximum residency (1150 sample(s))
45,576 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
Generation 0: 13739 collections, 0 parallel, 2.91s, 2.95s elapsed
Generation 1: 1150 collections, 0 parallel, 0.18s, 0.18s elapsed
INIT time 0.00s ( 0.00s elapsed)
MUT time 2.07s ( 2.28s elapsed)
GC time 3.09s ( 3.13s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 5.16s ( 5.41s elapsed)
的重要行是101,888 bytes maximum residency
,它說,在任何給定的點我的腳本使用的內存101 KB最多。我掠過的文件是44 MB。所以我認爲判決是:readFile
和hGetContents
都是懶惰的。
後續問題:
爲什麼我看到的內存7GB在堆上分配?對於在44 MB文件中讀取的腳本,這看起來非常高。
更新後續問題
貌似的堆上分配的內存數GB的不是非典型哈斯克爾,關注所以沒有原因。使用替代String
小號ByteString
S可內存使用率下降了不少:
81,617,024 bytes allocated in the heap
35,072 bytes copied during GC
78,832 bytes maximum residency (1 sample(s))
26,960 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
哼,你確定在用'putStrLn'實際編寫之前不需要建立整個'unlines'字符串嗎?我會嘗試像'Control.Monad.forM_(過濾器(isPrefixOf「導入」)內容)$ putStrLn'。然而,這只是一個猜測。 – 2012-03-17 01:19:32
@Riccardo:不,可以懶惰評估'unlines'。在'ghci'中試試'putStr $ unlines $ map show [1 ..]'。 – ephemient 2012-03-17 01:28:20
-O2神奇地解決了這個問題? – gspr 2012-03-17 07:55:13