Haskell: как использовать attoparsec для чтения вложенного списка из ByteString

У меня есть текстовый файл (~ 300 МБ) с вложенным списком, похожим на этот:

[[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 для анализа вложенного списка?


person mrsteve    schedule 11.11.2013    source источник
comment
Вы хотите прочитать весь список за один раз или обработать его по частям?   -  person Lambda Fairy    schedule 11.11.2013
comment
прочитайте список на одном дыхании.   -  person mrsteve    schedule 11.11.2013


Ответы (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)
person Ankur    schedule 11.11.2013
comment
теперь это как минимум на 50% быстрее для небольших файлов, возможно, даже больше для больших. отличный! - person mrsteve; 11.11.2013
comment
Для файла размером 50 МБ быстро используется 10 ГБ памяти. Как увеличить использование памяти? - person mrsteve; 11.11.2013
comment
Ну, [[Integer]] не самый эффективный формат памяти (вероятно, нет ничего хуже)... [[Int]] было бы немного лучше, но Vector of Vector of Int, вероятно, был бы правильным ответом ( и должно быть быстрее). Эсон должен знать, как это расшифровать. - person Jedai; 11.11.2013
comment
Я использую Int в данный момент. Попробую использовать Вектор. Интересно, проблема также в Aeson, поскольку я где-то читал, что Aeson очень неэффективен с точки зрения памяти, поскольку он предназначен для очень быстрого анализа небольших сообщений JSON. У меня 100гб ОЗУ, так что на данный момент все работает. - person mrsteve; 11.11.2013