XML::T...rmance(3pm)
β¨ NAME β¨
XML::TreePuller::CookBook::Performance β bestie, it's literally all about speeding up the flow of data through XML::TreePuller ππ
πΈ ABOUT πΈ
okay so. Wikipedia (and MediaWiki) dump files are giving chaos to parsers, and the vibe is: not complicated, just ENORMOUS. The English Wikipedia dump file is around 24 gigabytes, and the dump file that holds every revision ever made is estimated at around 1.5 terabytes (or even bigger, bestie π). So we're gonna go through parsing the Wikipedia dump files, faster and faster and faster. periodt.
π¦ Wikipedia dump format π¦
The dump file lowkey looks a little something like this:
<mediawiki version="0.4">
<siteinfo>
<sitename>Wikipedia</sitename>
<namespaces>
<namespace key="0"/>
<namespace key="1">Talk</namespace>
</namespaces>
</siteinfo>
<page>
<title>Perl</title>
<revision>
<contributor>
<username>A Random Monger</username>
</contributor>
<text>A nifty little language if I do say so myself!</text>
</revision>
</page>
<!-- 24 gigabytes more of XML goes here>
<page>
<title>C</title>
<revision>
<contributor>
<username>A Random Monger</username>
</contributor>
<text>Faster and even more dangerous.</text>
</revision>
</page>
</mediawiki>
π PROGRAMS π
π Print out a report from the dump file π
Let's build a report from the dump file, bestie: it'll have the version of the dump file, the site name, and the list of page titles. π«Ά
The most important thing to keep in mind with big dump files is that they are too large to fit the entire document into RAM. Because of this we need to have XML::TreePuller break the document up into chunks that will fit. We also want to access the version attribute on the root node but without having the entire document read into memory. iykyk π
#!/usr/bin/env perl
use strict;
use warnings;
use XML::TreePuller;
my $xml = XML::TreePuller->new(location => shift(@ARGV));
#read the mediawiki element but stop short
#of reading in a subelement
$xml->iterate_at('/mediawiki' => 'short');
$xml->iterate_at('/mediawiki/siteinfo/sitename' => 'subtree');
$xml->iterate_at('/mediawiki/page' => 'subtree');
print "Dump version: ", $xml->next->attribute('version'), "\n";
print "Sitename: ", $xml->next->text, "\n";
while($_ = $xml->next) {
#note that the root element is page, not mediawiki
print ' * ', $_->xpath('/page/title')->text, "\n";
}
π Print page titles and text π
Because the English Wikipedia dump files are so large, parsing them has been turned into a shoot-out to gauge the speed of various XML processing systems. The shoot-out is to print all the page titles and contents to STDOUT. This example processes the XML input of the simple English Wikipedia at 3.45 MiB/sec. slay β¨
use strict;
use warnings;
use XML::TreePuller;
binmode(STDOUT, ':utf8');
my $xml = XML::TreePuller->new(location => shift(@ARGV));
$xml->iterate_at('/mediawiki/page', 'subtree');
while(defined(my $e = $xml->next)) {
my $t = $e->xpath('/page');
print 'Title: ', $e->xpath('/page/title')->text, "\n";
print $e->xpath('/page/revision/text')->text;
}
π Print page titles and text but faster π
The previous example does not really use any of the features of XPath that warrant the additional processing overhead of involving it in our code. We can replace the xpath() calls with get_elements() which has less features but is faster. This code processes the XML input at 6.68 MiB/sec. ate, no crumbs π₯
use strict;
use warnings;
use XML::TreePuller;
binmode(STDOUT, ':utf8');
my $xml = XML::TreePuller->new(location => shift(@ARGV));
$xml->iterate_at('/mediawiki/page', 'subtree');
while(defined(my $e = $xml->next)) {
my $t = $e->xpath('/page');
print 'Title: ', $e->get_elements('title')->text, "\n";
print $e->get_elements('revision/text')->text;
}
β Print page titles and text - also faster β
There is one more way to solve this particular problem: we can ask the engine to iterate on both page title and text elements. This example runs at 7.9 MiB/sec. main character energy fr fr π
use strict;
use warnings;
use XML::TreePuller;
binmode(STDOUT, ':utf8');
my $xml = XML::TreePuller->new(location => shift(@ARGV));
$xml->iterate_at('/mediawiki/page/title', 'subtree');
$xml->iterate_at('/mediawiki/page/revision/text', 'subtree');
while(defined(my $e = $xml->next)) {
print 'Title: ', $e->text, "\n";
print $xml->next->text, "\n";
}
π COPYRIGHT π
All content is copyright Tyler Riddle; see the README for licensing terms. π«Ά
and that's the whole page, bestie π this one shipped as part of User Contributed Perl Documentation, perl v5.34.0, dated 2022-06-28. go parse something huge, ily ππ¦β¨
π¦ where this page comes from
- debian bookworm: libxml-treepuller-perl 0.1.2-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libxml-treepuller-perl 0.1.2-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libxml-treepuller-perl 0.1.2-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libxml-treepuller-perl 0.1.2-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libxml-treepuller-perl 0.1.2-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms