2015-06-14 3 views
0

Я написал синтаксический анализатор для большого файла csv, который работает с меньшим подмножеством, но исчерпывает память для строк ~ 1,5 м (фактический файл). После первоначального анализа всех элементов в списке (используя manyTill), я вместо этого использовал состояние парсера для их хранения в одном двоичном дереве поиска - это работало для большого файла.parsec закончился из памяти

С тех пор я разделил «тип элемента» на три отдельных типа и хочу сохранить их в своем собственном дереве, в результате получим три дерева разного типа. Эта версия, однако, работает только для небольшого тестового файла, в то время как у него не хватает памяти для большего.

import qualified Data.Tree.AVL as AVL 
import qualified Text.ParserCombinators.Parsec as Parsec 
---- 
data ENW = ENW (AVL.AVL Extent) (AVL.AVL Node) (AVL.AVL Way) 
---- used to be Element = Extent | Node | Way in a (Tree Element) - this worked 
csvParser :: Parsec String ENW ENW 
csvParser = do (Parsec.manyTill (parseL) Parsec.eof) >> Parsec.getState 
    where parseL = parseLine >> ((Parsec.newline >> return()) <|> Parsec.eof) 

parseLine :: Parsec String ENW() 
parseLine = parseNode <|> parseWay <|> parseExtents 

parseNode :: Parsec String ENW() 
parseNode = Parsec.string "node" *> (flip addNode <$> (Node <$> identifier <*> float <*> float)) >>= Parsec.updateState 
    where identifier = Parsec.tab *> (read <$> Parsec.many1 Parsec.digit) 
      float  = Parsec.tab *> (read <$> parseFloat) 

addNode :: ENW -> Node -> ENW 
addNode (ENW e n w) node = (ENW e (AVL.push (sndCC node) node n) w) 

parseWay и parseExtent следовать той же схеме, и все это начинается с

Parsec.runParser csvParser (ENW AVL.empty AVL.empty AVL.empty) "" input 

я не понимаю, как с помощью трех небольших деревьев вместо одной большой один может вызвать проблемы с памятью.

+0

Просто удар в темноте - тип данных Parsec является строгим в параметре «пользовательское состояние», в котором вы храните свои данные. Когда вы непосредственно хранили дерево в этом пользовательском состоянии, оно было строго проверено при разборе. Теперь, когда вы ввели ваши данные в коробку, не имеет значения, что у вас есть три дерева, только если вы поместите дерево в тип данных - деревья будут оцениваться лениво, что может привести к утечкам всякой памяти. Попробуйте сделать ваши поля вашего типа данных строгими. – user2407038

ответ

1

У вас есть веская причина не использовать Cassava? Он может использоваться для потоковой передачи данных CSV и, вероятно, более надежный, чем специальный синтаксический анализатор CSV. Мой собственный опыт показал, что он обладает отличной производительностью и может быть легко расширен, чтобы анализировать ваши собственные типы.

Редактировать: похоже, что вы работаете с данными с разделителями разделов, а не с разделителями-запятыми, но Cassava позволяет указать, какой разделитель разделяет столбцы. Также появляется, что данные, которые у вас есть, потенциально разные на каждом так что вам может понадобиться использовать «необработанный» формат Cassava, который возвращает векторную байтовую строку для каждой строки, которую вы можете проанализировать на основе первого элемента.

Я никогда не видел, чтобы кто-либо использовал пакет дерева AVL раньше, есть ли веская причина, по которой вы не используете более стандартные структуры? Этот пакет довольно старый (последнее обновление в 2008 году), и более свежие пакеты, скорее всего, будут работать лучше.

+0

Я просто пытаюсь изучить материал, и парсек казался стоящим. Да, это \ t и \ n разделенные значения, но я не знаю, есть ли «tsv». Сначала я использовал свой собственный тип дерева, но решил, что попробую кого-нибудь еще, прежде чем жаловаться. Мне нужно отсортировать элементы и не знать точное число, поэтому дерево было первым, что пришло мне в голову после того, как список (как вернулся manyTill) сразу же взорвался. – CryptoCamel

+0

PS: пакет avl является совпадением. Я понимаю, что для этой работы могут быть лучшие библиотеки, чем parsec, но я хотел посмотреть в parsec, чтобы узнать основные инструменты (впервые используя его здесь). Другое дело, что это, по-видимому, мало связано с самим синтаксическим анализом, и уклонение от проблемы не поможет мне в конечном итоге. – CryptoCamel

Смежные вопросы