Last active
October 8, 2020 18:51
-
-
Save klopp/262b0bbcb95151dea4beb356b705d132 to your computer and use it in GitHub Desktop.
Про парсеры XML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Поначалу захотелось Mojo::DOM. Когда-то использовал этот модуль в качестве замены HTML::DOM (он кошмарен), | |
и не разочаровался. Вменяемый набор методов, но... На XML от 100 Mb он так тормозил, что сразу отбросил. | |
OK, идём по классике: XML::LibXML. Из плюсов: | |
1) хороший комбайн с кучей возможностей (хотя, как и любое универсальное, для конкретных задач может быть громоздок) | |
2) вполне шустро | |
3) приятная мелочь: умеет обрабатывать NS в атрибутах (все следующие варианты - нет, и если мы не знаем заранее какие | |
NS могут встретиться, приходится заморачиваться отдельно; дальше отдельно про NS упоминать не буду) | |
Минусы: | |
1) см. предыдущий пункт 1, про комбайн :) | |
2) хочет много памяти | |
3) на файлах под полгига и больше может вылетать с совершенно невнятной диагностикой, например: | |
$ ls -sh psd7003.xml | |
684M psd7003.xml | |
$ ./xml-libxml.pl psd7003.xml | |
http error : Unknown IO error | |
Ссылка на код: https://gist.github.com/klopp/3fa3d0c6939fcafe1b29d827dfc9c315 | |
Дальше пробую XML::Twig. Да, как и зявлено, на больших файлах, с которыми не справляется XML::LibXML, не помирает. | |
Но скорость... Пока перемолотит XML мегабайт в 500, можно выспаться. Плюс - тот же недостаток, памяти хочет. | |
Ссылка на код: https://gist.github.com/klopp/b479c2a1439314379b79008bbd084edd | |
Использовать для данной задачи XML::Twig с применением пользовательских обработчиков тегов смысла не вижу, | |
так как фактически это надстройка над XML::Parser. И, как показывают тесты, рабает гораздо медленний. Хотя | |
и имеет более гибкий набор методов. | |
Ну вот и он, XML::Parser. Весьма и весьма. Потребности в памяти минимальные и вообще не зависят от размера | |
файла. Работает шустро, ведь обработчики мы задаём сами и не делаем ничего лишнего. Но есть один минус: в обработчик | |
Char может прилетать ненужный для данной задачи мусор из пробелов и переводов строк. В качестве первого костыля стал | |
просто не учитывать строки, состоящие только из пробельных символов. Что для задачи не очень корректно. | |
Ссылка на код: https://gist.github.com/klopp/aadf718977ae698e407c2edf243310c3 | |
Пробую другой костыль: ввести список тегов, внутри которых текст обрабатывается "as is", остальные пропускаем. | |
А почему бы и нет? В простейшем случае это параграф. Получается лучше, да и скорость. | |
Код: https://gist.github.com/klopp/28a1b3d32fbef549c8ac11c245375580 | |
На данный момент это лидер. Но... | |
Как сишник не могу пройти мимо XML::Fast :) Да, память отжирает. Хоть и намного меньше LibXML/Twig. Но по скорости | |
уделывает всех: | |
$ ls -sh psd7003.xml | |
684M psd7003.xml | |
$ time ./xml-parser-tag.pl psd7003.xml | |
All characters : 2 970 951 | |
Non-whitespace characters : 2 870 720 | |
Internal links : 0 | |
real 1m30.832s | |
user 1m30.524s | |
sys 0m0.172s | |
$ time ./xml-fast.pl psd7003.xml | |
All characters : 2 970 951 | |
Non-whitespace characters : 2 870 720 | |
Internal links : 0 | |
real 0m55.859s | |
user 0m53.928s | |
sys 0m1.880s | |
$ ls -sh SwissProt.xml | |
110M SwissProt.xml | |
$ time ./xml-parser-tag.pl SwissProt.xml | |
All characters : 4 727 868 | |
Non-whitespace characters : 4 697 952 | |
Internal links : 0 | |
real 0m16.518s | |
user 0m16.484s | |
sys 0m0.028s | |
$ time ./xml-fast.pl SwissProt.xml | |
All characters : 4 727 868 | |
Non-whitespace characters : 4 697 952 | |
Internal links : 0 | |
real 0m11.848s | |
user 0m11.484s | |
sys 0m0.360s | |
Код: https://gist.github.com/klopp/0322d9d7fa8d3e1498951c5aa14a71d1 | |
P.S. XML::Bare, XML::Hash::XS и XML::Simple рассматривать смысла не вижу. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment