URIパースモジュールのベンチマーク

バッチ処理URIのパースにURIモジュール使ってたのですが、
プロファイルとってみたらこいつが結構ボトルネックになっていたので
別のモジュールを探していたらURI::Splitというのがあったのでベンチマークとってみた。*1

ベンチマークスクリプト

use strict;
use warnings;
use URI;
use URI::Split;
use Benchmark qw(timethese  cmpthese);

my $urlstr = 'http://hogehoge.com/hoge/fuga/index.html?hoge=hoge&foo=1&foo=2&bar=3&bar=4';
my $count = 100000;


my $uri = URI->new($urlstr);
print "----------URI----------\n";
print $uri->scheme . "\n";
print $uri->host . "\n";
print $uri->path . "\n";
print $uri->query . "\n";

print "----------URI::Split----------\n";
my ($scheme, $auth, $path, $query, $frag) = URI::Split::uri_split($urlstr);
print $scheme . "\n";
print $auth . "\n";
print $path . "\n";
print $query . "\n";
print "------------------------------\n";


my $comp = timethese(
    $count,
    {
        uri_parse => \&uri_parse,
        urisp_parse => \&urisp_parse,
        uri_parsejoin => \&uri_parsejoin,
        urisp_parsejoin => \&urisp_parsejoin,
    }
);

cmpthese $comp;

sub uri_parse {
    my $uri = URI->new($urlstr);
}
sub urisp_parse {
    my ($scheme, $auth, $path, $query, $frag) = URI::Split::uri_split($urlstr);
}
sub uri_parsejoin {
    my $uri = URI->new($urlstr);
    my $urijoin = $uri->scheme .  $uri->host . $uri->path . $uri->query ;
}
sub urisp_parsejoin {
    my ($scheme, $auth, $path, $query, $frag) = URI::Split::uri_split($urlstr);
    my $urijoin = URI::Split::uri_join($scheme, $auth, $path, $query, $frag);
}

結果

----------URI----------
http
hogehoge.com
/hoge/fuga/index.html
hoge=hoge&foo=1&foo=2&bar=3&bar=4
----------URI::Split----------
http
hogehoge.com
/hoge/fuga/index.html
hoge=hoge&foo=1&foo=2&bar=3&bar=4
------------------------------
Benchmark: timing 100000 iterations of uri_parse, uri_parsejoin, urisp_parse, urisp_parsejoin...
 uri_parse:  2 wallclock secs ( 1.47 usr +  0.00 sys =  1.47 CPU) @ 68027.21/s (n=100000)
uri_parsejoin:  3 wallclock secs ( 3.46 usr +  0.00 sys =  3.46 CPU) @ 28901.73/s (n=100000)
urisp_parse:  1 wallclock secs ( 0.59 usr +  0.00 sys =  0.59 CPU) @ 169491.53/s (n=100000)
urisp_parsejoin:  1 wallclock secs ( 1.25 usr +  0.00 sys =  1.25 CPU) @ 80000.00/s (n=100000)
                    Rate uri_parsejoin    uri_parse urisp_parsejoin  urisp_parse
uri_parsejoin    28902/s            --         -58%            -64%         -83%
uri_parse        68027/s          135%           --            -15%         -60%
urisp_parsejoin  80000/s          177%          18%              --         -53%
urisp_parse     169492/s          486%         149%            112%           --


うむ。URI::Splitの方が全然速いっすね。
パースするだけならこっちの方が良さげ。

以下、URL関係の便利モジュール参考リンク

URLを触る時は、URIperlモジュール名)が超便利だと思う。
http://perl-mongers.org/2008/06/urluri.html
URLを触る時は、URI(モジュール名)以外も知っておくと吉
http://perl-mongers.org/2008/06/uri-and-more.html
CPAN - URI::Escape::XS Released!
http://blog.livedoor.jp/dankogai/archives/50818918.html

*1:環境はUbuntu 9.10のperl5.10.0です