Haskell, Parsec 2 и тормоза
Apr. 26th, 2010 01:14 amПомня о том, какое бурление вызвало сравнение скорости Лиспа с другими языками в прошлом номере ПФП, прошу помощи зала не допустить несправедливости. Я сейчас доделываю сравнение скорости разных методов парсинга, сделал вариант на Хаскеле на базе Parsec2, и получившаяся скорость мне совсем не нравится. До этого на Хаскеле не писал, поэтому наверняка мог сильно налажать. Исходник (~70 строк) выложил здесь.
Суть программы - чтение карты формата OpenStreetMap и вычисление ее реальных границ - минимальных и максимальных значений широты и долготы встреченных точек. Собирал ее с GHC 6.8.3 и 6.10.1, Parsec 2.1.0.1, команда для сборки:
Сейчас скорость получается около 3 МБ/с.
Пример простой карты тут. Скорость тестировал на карте Сингапура (архив 1.2 МБ).
Прошу более опытных товарищей глянуть на исходник и указать на явные косяки. Можно ли заметно ускорить программу без сильных изменений описанной там грамматики?
Суть программы - чтение карты формата OpenStreetMap и вычисление ее реальных границ - минимальных и максимальных значений широты и долготы встреченных точек. Собирал ее с GHC 6.8.3 и 6.10.1, Parsec 2.1.0.1, команда для сборки:
ghc -O2 -package parsec bounds.hs -o bounds
Сейчас скорость получается около 3 МБ/с.
Пример простой карты тут. Скорость тестировал на карте Сингапура (архив 1.2 МБ).
Прошу более опытных товарищей глянуть на исходник и указать на явные косяки. Можно ли заметно ускорить программу без сильных изменений описанной там грамматики?
no subject
Date: 2010-04-28 07:14 am (UTC)Краткий диагноз - хаскель cpu bound. плюсы IO bound.
Дальше речь идет о хрюшке x86 тк померять линупс на работе лениво - туда еще хаскель через одминов пропихивать, семерку дома лениво - надо дома сползти с дивана. Макось меня послала скачивать новый xcode иначе haskell platform из портов не ставится - так что тоже лениво.
На холодном файловом кэше код который я привел побить неудается.
С более точным таймером (timeBeginPeriod(1),timeGetTime()) предложенный код работает ~167ms (собранный целиком статикой с stlport и тп)(горячий кэш). На холодном 170-200ms.
На горячем кеше предел мечтаний в районе 115-130ms но дергается - антивирус может быть а может и еще какая ерунда. Имхо написание потокового парсера может оправдать только требование кушать реально большие файлы. Как показало вскрытие pugixml делает fread( filesize ) что быстро удаляется от оптимума при росте размера xml файлов дальше десятков мб.
Вот собсно и все про перформанс _этого_ примера - спасибо пост и комментарии про lpeg и от thesz были весьма интересны - я даже полистал доки spirita - там возможно решение на PEG портируется без переделок алгоритма.
no subject
Date: 2010-04-28 08:20 am (UTC)разумеется для горячего файлового кэша плюсы тоже сpu bound - так что можно еще в пару раз.
перф. для меня это хобби для отдыха :) Если вспомню с какой стороны парсеры можно будет пойти на спортивный результат :D
no subject
Date: 2010-04-28 08:49 am (UTC)no subject
Date: 2010-04-28 12:49 pm (UTC)правда и хаскельный вариант на хрюше 32 упал с
bounds.exe: out of memory
интересно под Win64 есть возможность собрать ваш пример на хаскеле? или только 32 ?
no subject
Date: 2010-04-28 01:23 pm (UTC)no subject
Date: 2010-05-02 11:18 am (UTC)Если захотеть поглумиться над industrial c++ то нужно выманить на спор деятелей с xerces или msxml на потоковый парсинг. пусть заюзают какой-нибудь sax2 и почувствуют разницу с каким-нибудь фп-yacc :).