lomeo: (лямбда)
[personal profile] lomeo
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 кода?

Date: 2008-08-01 03:33 pm (UTC)
From: [identity profile] thesz.livejournal.com
По идее, должны срабатывать.

При задании правил, по идее, можно указать этапы компиляции, на которых они будут срабатывать.

The "[2]" means that the rule is active in Phase 2 and subsequent phases. The inverse notation "[~2]" is also accepted, meaning that the rule is active up to, but not including, Phase 2.

http://www.haskell.org/ghc/docs/6.8.2/html/users_guide/rewrite-rules.html

Date: 2008-08-01 04:01 pm (UTC)
From: [identity profile] lomeo.livejournal.com
Указывал 1,2. На самом деле, указание это только ограничение, как я понял - мне бы наоборот.

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

Date: 2008-08-01 04:44 pm (UTC)

Date: 2008-08-20 08:36 am (UTC)
From: [identity profile] virkony.livejournal.com
может {-# NOINLINE [~1] satisfy #-} (что б не заинлайнилось раньше чем твои правила заметят его)?

Date: 2008-08-20 09:01 am (UTC)
From: [identity profile] lomeo.livejournal.com
Там проблема в том, что digit не инлайнится. Вчера увидел по -ddump-simpl-iterations.

Написал свой

{-# INLINE myDigit #-}
myDigit :: Parsec BS.ByteString () Char
myDigit = satisfy isDigit -- "digit"

так инлайнится, а заменю () на u - нет. Имеется в виду тип

myDigit :: Parsec BS.ByteString u Char

Profile

lomeo: (Default)
Dmitry Antonyuk

December 2015

S M T W T F S
  12345
6789101112
131415 16171819
20212223242526
2728293031  

Style Credit

Expand Cut Tags

No cut tags
Page generated Oct. 23rd, 2017 08:32 pm
Powered by Dreamwidth Studios