Ради интереса я написал быстрый скрипт командной строки Racket для анализа старых файлов состояния Unix.Файлы Fortune - это просто гигантские текстовые файлы с одним %
на пустой строке, разделяющей записи.
В качестве первого быстрого взлома я написал следующий код Racket:
(define fortunes
(with-input-from-file "fortunes.txt"
(λ ()
(regexp-split #rx"%" (port->string)))))
Я думал, что это будет работать почти мгновенно.Вместо этого требуется очень много времени для запуска - порядка пары минут.Для сравнения, то, что я считаю эквивалентным Python:
with open('fortunes.txt') as f:
fortunes = f.read().split('%')
выполняется немедленно, с эквивалентными результатами для кода Racket.
Что я здесь не так делаю?Да, есть некоторые очевидные низко висящие плоды, например, я уверен, что было бы лучше, если бы я не вылил весь файл в ОЗУ с port->string
, но поведение настолько патологически плохое, что я чувствую, что долженделать что-то глупое на гораздо более высоком уровне, чем это.
Есть ли более похожий на ракетку способ сделать это с одинаково лучшей производительностью?Racket I / O действительно плох для некоторых операций?Есть ли способ профилировать мой код немного глубже, чем наивный профилировщик в DrRacket, чтобы я мог выяснить, что о данной строке вызывает проблему?
EDIT : Файл удачи, который я использую, - это FreeBSD, найденный по адресу http://fortunes.cat -v.org / freebsd / , который весит около 2 МБ.Лучшее время выполнения для Racket 5.1.3 x64 на OS X Lion было:
real 1m1.479s
user 0m57.400s
sys 0m0.691s
Для Python 2.7.1 x64 это было:
real 0m0.057s
user 0m0.029s
sys 0m0.015s
Право Элая на то, что время идетпотрачено почти целиком в regexp-split
(хотя полная секунда, по-видимому, потрачено в port->string
), но мне не ясно, есть ли предпочтительный, но такой же простой метод.