Haskell 代码中的空间泄漏在哪里?

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

我试图通过交替行将一个文件拆分为两个单独的文件。(即第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 (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
方法更清晰、更简单。