測ってみた

前回のエントリーブクマコメントに、id:gfxさんからCoroからFurlを使う方法を書いていただいていたので、同じ環境でベンチしてみました。

gfx++

Coro+Furlのコードはhttps://gist.github.com/665488から。

use strict;
use warnings;
use 5.0100;
use Furl;
use AnyEvent::HTTP;
use Coro;
use Coro::Select;
use Coro::AnyEvent;
use Coro::Semaphore;
use Benchmark qw/timethese cmpthese/;


# request
my $url = 'http://ext.nicovideo.jp/api/getthumbinfo/';
my $retry = 3;

open my $fh, '<:utf8', '_tmp';
my @list;
for (0 .. 100) {
	my $line = <$fh>;
	chomp $line;
	push @list, $url . $line;
}
close $fh;

cmpthese timethese 1, {
	CoroFurl => sub {
		my @coros;
		foreach my $url(@list) {
			chomp $url;
		    push @coros, async {
		        print "fetching $url\n";
		        my $furl = Furl->new();
		        my $res = $furl->get($url);
		        print "$url: ", $res->status_line, "\n";
		    };
		}

		$_->join for @coros;
	},
	Coro => sub {
		my $sem = Coro::Semaphore->new(5);
		my @coros;
		for my $video_id (@list) {
			chomp $video_id;
			push @coros, async {
				my $guard = $sem->guard;
				http_get $video_id, Coro::rouse_cb;
				my ($data, $hdr) = Coro::rouse_wait;
				if ($hdr->{Status} =~ /^2/) {
					 #print "finish, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				} else {
					 warn "error, $hdr->{Status} $hdr->{Reason} $hdr->{URL}\n";
				}
			};
		}
		$_->join for @coros;
	},
};

で、結果。Furlは早いし、Coro::Select使うだけで簡単でいいですね。

Benchmark: timing 1 iterations of Coro, CoroFurl...
      Coro: 22 wallclock secs ( 0.38 usr +  0.11 sys =  0.49 CPU) @  2.06/s (n=1)
            (warning: too few iterations for a reliable count)
  CoroFurl:  8 wallclock secs ( 0.05 usr +  0.05 sys =  0.09 CPU) @ 10.64/s (n=1)
            (warning: too few iterations for a reliable count)
           Rate     Coro CoroFurl
Coro     2.06/s       --     -81%
CoroFurl 10.6/s     416%       --