lomeo: (лямбда)
Dmitry Antonyuk ([personal profile] lomeo) wrote2008-08-01 07:04 pm

Parsec3 траблы

3-й parsec, как известно, построен для работы с Data.ByteString, что должно неимоверно поднять скорость парсинга, по сравнению с обычным строковым.


На ICFPC [livejournal.com profile] _adept_ категорически высказался против использования 3-его parsec-а. Аргументом была именно скорость его работы. В качестве теста был представлен несложный разбор 15М файла. Жуткий 3-й парсек тормозил со страшной силой, причём на ByteString (что обычных, что lazy) даже был медленнее строк.

Всё таки это неправильно. Я переписал простой разборщик (не Parsec!) строк на ByteString, скорость возрасла в два раза. Значит, дело не в кривых ByteString. Хотя не думаю, что тут можно сомневаться. Потом после специализации нескольких важных функций в Parsec он почти догнал второй, отставая менее, чем в два раза.

Основная причина, устранив которую мы резко поднимаем производительность - это замена для many, который возвращает [a], хотя чаще всего нам нужен поток символов. В нашем случае это ByteString.

Просто сделать не получилось, я написал
manyChars :: ... -> Parsec ... ByteString


Причём специализации тут уже совершенно не нужны.

Добавил следующие правила

{-# RULES
    "many/satisfy" forall p. many (satisfy p) = manyChars p
 #-}
{-# RULES
    "many/satisfyErr"   forall p s. many (satisfy p  s) = manyChars p  s
 #-}


Но они работают только при явном наличии many (satisfy f) или many (satisfy p s), если же у нас выражение many digit, где digit сам является satisfy isDigit "digit", то правило не срабатывает.

Т.е.
digit = satisfy isDigit  "digit"
many digit -- не работает
many (satisfy isDigit  "digit") -- работает


Ставлю digit INLINE - по барабану.

Как то можно заставить срабатывать правила на полученном после, скажем, INLINE кода?

[identity profile] deni-ok.livejournal.com 2008-08-01 04:34 pm (UTC)(link)
Спросил бы в ru_declarative, может кто ещё откликнется...

[identity profile] lomeo.livejournal.com 2008-08-01 04:44 pm (UTC)(link)
ок