RSSのパース速度の比較

2009年2月23日
| コメント(0) | トラックバック(2) RSSのパース速度の比較

色々と触発されてやってみた。

参考:
Perl で XML の処理はどれが速いかベンチ : NDO::Weblog
iandeth. - XML::Simple は遅い説における意外な落とし穴
XML::Simple におけるパーサーの実行速度比較 - naoyaのはてなダイアリー

Benchmark: running XML::FeedPP, XML::LibXML, XML::RSS, XML::RSS::LibXML, XML::RSS::Parser, XML::RSSLite, XML::Simple, regexp for at least 3 CPU seconds...
     XML::FeedPP:  2 wallclock secs ( 3.02 usr +  0.00 sys =  3.02 CPU) @ 55.37/s (n=167)
     XML::LibXML:  3 wallclock secs ( 3.25 usr +  0.02 sys =  3.27 CPU) @ 496.02/s (n=1620)
        XML::RSS:  4 wallclock secs ( 3.27 usr +  0.00 sys =  3.27 CPU) @  2.76/s (n=9)
XML::RSS::LibXML:  4 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @ 49.54/s (n=161)
XML::RSS::Parser:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @  3.76/s (n=12)
    XML::RSSLite:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 112.10/s (n=352)
     XML::Simple:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 61.13/s (n=192)
          regexp:  4 wallclock secs ( 3.28 usr +  0.00 sys =  3.28 CPU) @ 6340.14/s (n=20802)
 
                   Rate XML::RSS XML::RSS::Parser XML::RSS::LibXML XML::FeedPP XML::Simple XML::RSSLite XML::LibXML regexp
XML::RSS         2.76/s       --             -27%             -94%        -95%        -95%         -98%        -99%  -100%
XML::RSS::Parser 3.76/s      37%               --             -92%        -93%        -94%         -97%        -99%  -100%
XML::RSS::LibXML 49.5/s    1697%            1216%               --        -11%        -19%         -56%        -90%   -99%
XML::FeedPP      55.4/s    1909%            1371%              12%          --         -9%         -51%        -89%   -99%
XML::Simple      61.1/s    2118%            1524%              23%         10%          --         -45%        -88%   -99%
XML::RSSLite      112/s    3967%            2878%             126%        102%         83%           --        -77%   -98%
XML::LibXML       496/s   17894%           13078%             901%        796%        711%         342%          --   -92%
regexp           6340/s  229906%          168336%           12698%      11350%      10272%        5556%       1178%     --

読み込んだRSSファイルは、「はてなブックマーク - タグ - 石原さとみ(タグ「石原さとみ」を含む新着エントリー)」な感じの20件です。

正規表現はパターンがちがちで応用は利きませんが、速さはピカイチ。
XML::LibXMLはXPathがよくわからないのでアレですが、使いこなせれば速さも申し分なしです。
XML::RSSLiteが結構頑張っている印象ですね。関数呼び出しなのが、この中では違和感ありますが。
XML::Simpleのパーサーは、無難にXML::Parserを指定することでそれなりに速いです。ただ、手元の環境だとXML::SAX::ExpatXSが最速だったのですが。
ま、環境によるんでしょうね…。
XML::FeedPPがかなり健闘していると思います。ファイル構成もシンプル(1枚だけ)だし、汎用性もあるし、レンタルサーバーにも最適でしょうね。
これからRSSなどを扱うならXML::FeedPPが便利でしょうね。

ソースコードは以下のとおり。
使う場合はRSSファイルを適宜用意してください。

ソースコード

use strict;
use warnings;
use Data::Dumper;
 
use Benchmark qw(:all);
use FileHandle;
use XML::LibXML;
use XML::RSS;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
use XML::RSS::LibXML;
use XML::RSS::Parser;
use XML::FeedPP;
use XML::RSSLite;
 
my $rss_file = "../satomi.xml";
my $fh = FileHandle->new($rss_file)
    or die "cannot open $rss_file: $!";
local $/; # slurp mode
our $content = $fh->getline;
$fh->close;
 
cmpthese(timethese(0,
{
    'regexp'           => \&with_regexp,
    'XML::Simple'      => \&with_xml_simple,
    'XML::RSS'         => \&with_xml_rss,
    'XML::LibXML'      => \&with_xml_libxml,
    'XML::RSS::LibXML' => \&with_xml_rss_libxml,
    'XML::RSS::Parser' => \&with_xml_rss_parser,
    'XML::FeedPP'      => \&with_xml_feedpp,
    'XML::RSSLite'     => \&with_xml_rsslite,
}));
 
sub with_xml_rsslite {
    my @links = ();
    my %result;
    parseRSS(\%result, \$content);
    for my $item (@{$result{item}}) {
        push @links, $item->{link};
    }
#    print Dumper \@links;
}
 
sub with_xml_feedpp {
    my @links = ();
    my $feed = XML::FeedPP->new($content);
    foreach my $item ( $feed->get_item() ) {
        push @links, $item->link;
    }
#    print Dumper \@links;
}
 
sub with_xml_rss_parser {
    my @links = ();
    my $parser = XML::RSS::Parser->new;
    my $feed = $parser->parse_string($content);
    foreach my $item ( $feed->query('item') ) {
        push @links, $item->query('link')->text_content;
    }
#    print Dumper \@links;
}
 
sub with_regexp {
    my $pattern = "<item .*?>.*?<link>(.*?)</link>.*?</item>";
    my @links =
        ($content =~ m/$pattern/smg);
#    print Dumper \@links;
}
 
sub with_xml_simple {
    my @links = ();
    my $parser = XML::Simple->new;
    my $data = $parser->XMLin($content, ForceArray => 1);
    for my $item (@{$data->{item}}) {
        push @links, $item->{link}[0];
    }
#    print Dumper \@links;
}
 
sub with_xml_rss {
    my @links = ();
    my $rss = XML::RSS->new;
    $rss->parse($content);
    for my $item (@{$rss->{items}}) {
        push  @links, $item->{link};
    }
#    print Dumper \@links;
}
 
sub with_xml_libxml {
    my @links =();
    my $parser = XML::LibXML->new;
    my $doc = $parser->parse_string($content);
    my @nodes = $doc->findnodes(
        "//*[local-name()='item']/*[local-name()='link']/text()"
    );
    for my $node (@nodes) {
        push @links, $node->nodeValue;
    }
#    print Dumper \@links;
}
 
sub with_xml_rss_libxml {
    my @links = ();
    my $rss = XML::RSS::LibXML->new;
    $rss->parse($content);
    for my $item (@{$rss->{items}}) {
        push  @links, $item->{link};
    }
#    print Dumper \@links;
}

トラックバック(2)

このブログ記事に対するトラックバックURL:

このブログ記事を参照しているブログ一覧:

ソースだけでなくタイトルもパクリですが。 実行結果は環境によって変わるんでしょう... 続きを読む

何かで使えそうな気がして、Feed(RSSとかAtomとか)をウェブから取ってき... 続きを読む

コメントする

Google検索

Last.fm

このブログ記事について

このページは、のぶりんが2009年2月23日 22:43に書いたブログ記事です。

ひとつ前のブログ記事は「CPAN よく使われるネーム王選手権」です。

次のブログ記事は「XML::Simple におけるパーサーの実行速度比較」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログのライセンスは クリエイティブ・コモンズライセンス.
Powered by Movable Type