Haskell 代码中的空间泄漏在哪里?
我试图通过交替行将一个文件拆分为两个单独的文件。(即第1、3、5、7……行写入文件1,第2、4、6、8……行写入文件2) 我正在处理的文件约为700MB,因此当我看到内存使用量超过6GB时,我知道有问题Haskell 代码中的空间泄漏在哪里?,haskell,memory-leaks,Haskell,Memory Leaks,我试图通过交替行将一个文件拆分为两个单独的文件。(即第1、3、5、7……行写入文件1,第2、4、6、8……行写入文件2) 我正在处理的文件约为700MB,因此当我看到内存使用量超过6GB时,我知道有问题 main :: IO() main = withFile splitFile ReadMode splitData where splitData h = do dataSet <- lines <$> hGetContents h let
main :: IO()
main = withFile splitFile ReadMode splitData
where
splitData h = do
dataSet <- lines <$> hGetContents h
let (s1,s2) = foldl' (\(l,r) x -> (x:r,l)) ([],[]) dataSet
writeFile testFile $ unlines s1
writeFile trainingFile $ unlines s2
main::IO()
main=withFile splitFile ReadMode splitData
哪里
splitData h=do
数据集正如@dfeuer在评论中提到的,使用writeFile
将强制写入整个字符串以进行计算,这也将强制读取整个输入。导致空间泄漏的原因是,在写入第一个文件时,整个第二个文件必须保存在内存中,而很明显,一次只能在内存中保存一行。事实上,解决办法是一行一行地写:
import Control.Monad
import System.IO
main :: IO ()
main =
withFile splitFile ReadMode $ \hIn ->
withFile testFile WriteMode $ \hOdd ->
withFile trainingFile WriteMode $ \hEven ->
zipWithM_ hPutStrLn (cycle [hOdd, hEven]) . lines =<< hGetContents hIn
import-Control.Monad
导入系统.IO
main::IO()
主要=
withFile splitFile ReadMode$\hIn->
withFile testFile WriteMode$\hOdd->
withFile trainingFile WriteMode$\hEvent->
zipWithM_uhputstrln(循环[hOdd,hEven])。lines=我不会在这里使用
,因为运算符优先级不明显(或者我会使用括号,但最有可能的是我会使用fmap
)。另外,无论是foldl
还是foldl'
,都不会在这里执行您想要的操作。如果需要,可以使用foldr
,但user2407038的zipWithM
方法更清晰、更简单。