【问题标题】:Haskell: How to use attoparsec in order to read a nested list from a ByteStringHaskell:如何使用 attoparsec 从 ByteString 读取嵌套列表
【发布时间】:2013-11-11 04:00:25
【问题描述】:

我有一个带有嵌套列表的文本文件(约 300 MB 大),类似于这个:

[[4, 9, 11, 28, 30, 45, 55, 58, 61, 62, 63, 69, 74, 76, 77, 82, 87, 92, 93, 94, 95], [4, 9, 11, 28, 30, 45, 55, 58, 61, 62, 63, 69, 74, 76, 77, 82, 87, 92, 93, 94],[4, 9, 11, 28, 30, 45, 55, 58, 61, 62, 63, 69, 74, 76, 77, 82, 85, 87, 92, 93, 94, 95]]

这是我将文件读入haskell Integer 列表的程序:

import qualified Data.ByteString as ByteStr

main :: IO ()

-- HOW to do the same thing but using ByteStr.readFile for file access?
main = do fContents <- readFile filePath 
          let numList = readNums fContents
          putStrLn (show nums)

这适用于小文本文件,但我想使用ByteString 快​​速读取文件。我发现 ByteString 没有read 函数,你应该在 attoparsec 中编写自己的解析器,因为它支持解析 ByteStrings。

如何使用attoparsec解析嵌套列表?

【问题讨论】:

  • 你想一口气读完整个列表,还是分块处理?
  • 一口气读完清单。

标签: parsing haskell bytestring attoparsec


【解决方案1】:

数据似乎是 JSON 格式,所以您可以使用 Data.Aeson decode 函数,该函数适用于 ByteString

import qualified Data.ByteString.Lazy as BL
import Data.Aeson
import Data.Maybe

main = do fContents <- BL.readFile filePath 
          let numList = decode fContents :: Maybe [[Int]]
          putStrLn (show $ fromJust numList)

【讨论】:

  • 现在小文件的速度至少快 50%,大文件的速度可能更快。太棒了!
  • 对于一个 50MB 的文件,这很快就会使用 10GB 的内存。如何提高内存使用率?
  • 嗯 [[Integer]] 不是最节省内存的格式(可能没有更糟的)... [[Int]] 会好一点,但是 Vector of Vector Int 可能是正确的答案(它也应该更快)。 Aeson 应该知道如何完美解码。
  • 我现在正在使用 Int。将尝试使用 Vector。我想知道问题是否也是 Aeson,因为我在某处读到 Aeson 的内存效率非常低,因为它旨在解析非常快速的小型 JSON 消息。我有 100GB 的 RAM,所以目前它可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
相关资源
最近更新 更多