我正在尝试使用Cassava将CSV文件加载到内存中作为向量的向量。我的程序确实可以工作,但对于一个50MB的CSV文件使用了大量的内存,我不明白为什么。
我知道使用Data.Csv.Streaming处理大文件应该更好,但我认为50MB仍然可以。我尝试了Data.Csv和Data.Csv.Streaming,并使用GitHub项目页面上更多或更少规范的示例,我还尝试实现自己的解析器,输出向量的向量(我基于attoparsec-csv https://hackage.haskell.org/package/attoparsec-csv编写代码),所有这些解决方案都使用约2000MB的内存!我确定我做错了什么。正确的做法是什么?
我的最终目标是将数据完全加载到内存中以供以后进行进一步处理。例如,我可以将数据拆分成有趣的矩阵,并使用Hmatrix处理它们。
以下是我尝试使用Cassava的两个程序:
1 / 使用Data.Csv
请注意,我不会提供基于attoparsec-csv制作的程序,因为它与List几乎完全相同,而Vector则不同。该解决方案的内存使用仍然非常差。
有趣的是,在Data.Csv.Streaming解决方案中,如果我仅使用Data.Foldable.for_打印我的数据,一切都非常快,内存使用量为2MB。这让我想到我的问题与构造Vector的方式有关。可能积累了thunk而不是将原始数据堆叠到紧凑的数据结构中。
感谢您的帮助,
安托万
我知道使用Data.Csv.Streaming处理大文件应该更好,但我认为50MB仍然可以。我尝试了Data.Csv和Data.Csv.Streaming,并使用GitHub项目页面上更多或更少规范的示例,我还尝试实现自己的解析器,输出向量的向量(我基于attoparsec-csv https://hackage.haskell.org/package/attoparsec-csv编写代码),所有这些解决方案都使用约2000MB的内存!我确定我做错了什么。正确的做法是什么?
我的最终目标是将数据完全加载到内存中以供以后进行进一步处理。例如,我可以将数据拆分成有趣的矩阵,并使用Hmatrix处理它们。
以下是我尝试使用Cassava的两个程序:
1 / 使用Data.Csv
import qualified Data.ByteString.Lazy as BL
import qualified Data.Vector as V
import Data.Csv
import Data.Foldable
main = do
csv <- BL.readFile "train.csv"
let Right res = decode HasHeader csv :: Either String (V.Vector(V.Vector(BL.ByteString)))
print $ res V.! 0
2/ 使用Data.Csv.Streaming
{-# LANGUAGE BangPatterns #-}
import qualified Data.ByteString.Lazy as BL
import qualified Data.Vector as V
import Data.Csv.Streaming
import Data.Foldable
main = do
csv <- BL.readFile "train.csv"
let !a = decode HasHeader csv :: Records(V.Vector(BL.ByteString))
let !res = V.fromList $ Data.Foldable.toList a
print $ res V.! 0
请注意,我不会提供基于attoparsec-csv制作的程序,因为它与List几乎完全相同,而Vector则不同。该解决方案的内存使用仍然非常差。
有趣的是,在Data.Csv.Streaming解决方案中,如果我仅使用Data.Foldable.for_打印我的数据,一切都非常快,内存使用量为2MB。这让我想到我的问题与构造Vector的方式有关。可能积累了thunk而不是将原始数据堆叠到紧凑的数据结构中。
感谢您的帮助,
安托万
ByteString
有关。我通过定义strictRead path = evaluate . force <$> BL.read path
来解决了这个问题,但我不认为这是最好的答案。你也可以尝试使用ByteString.toLazy <$> ByteString.Strict.readFile path
,但我从未测试过。 - guaraqe(evaluate . force) =<< BL.read path
,但在展开之后应该与你的代码等效。嗯,所以我认为解决方案是使用cassava
中的其他模块,很抱歉我无法提供帮助,我也对答案感兴趣。如果这里没有答案,请尝试在subreddit上询问,那里非常活跃。 - guaraqe