日向夏特殊応援部隊

俺様向けメモ

Cache::Memcached::GetParserXSを使うと速くなるのか?

試してみた。あと追記・修正した。

追記(2007-09-11T11:20:32+09:00)

激しく既出だった。(d:id:spiritloose:20060909:1157767723)
id:spiritlooseさんとやりたい方向性がかなり被ってるなぁ。w

あと、

新しいbinary protocol使えばもっと差が出るかも

むむ!後で調べる。

前置き

ちなみにCache::Memcachedの1.21*1から使えるCache::Memcached::GetParserの代わりがCache::Memcached::GetParserXSです。

newする際に、

my $cache = Cache::Memcached->new({
                    servers => $servers,
                    parser_class => ''Cache::Memcached::GetParserXS
                  });

のようにダイレクトに指定してもいいし、もしCache::Memcached::GetParserXSがインストール済みならば、勝手に使ってくれます。

環境変数NO_XSに1を代入しておくと、newの時に直接指定していない場合に使わないようになります。

追記

もともと書いたベンチだとこのモジュールの特性を活かしきれない事に気づいたので修正。

ベンチマークスクリプト

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw(:all);
use Getopt::Long;
use Cache::Memcached;
use Cache::Memcached::GetParserXS;

my ($servers, $count);

GetOptions(
        "servers=s@" => \$servers,
        "count=s" => \$count
);

my $cache = Cache::Memcached->new({
        servers => $servers,
        parser_class => 'Cache::Memcached::GetParser'
});

my $cache_xs = Cache::Memcached->new({
        servers => $servers,
        parser_class => 'Cache::Memcached::GetParserXS'
});

sub cache_test {
        my $cache = shift;
        my %data;
        @data{("a".."z")} = (1 .. 26);

#       for my $key (keys %data) {
#               $cache->set($key, $data{$key});
#              $cache->get($key);
#                $cache->delete($key);
#       }
        $cache->set("test", \%data);
        $cache->get("test");
        $cache->delete("test");
}

my $result = timethese($count, {
        'no_xs' => sub { cache_test($cache); },
        'use_xs' => sub { cache_test($cache_xs); }
});

cmpthese $result;

bench_memcached.plとかで保存して、実行権限与えて、

$ ./bench_memcached.pl --servers localhost:11211 --count 100

とかで実行します。

100回のとき

Benchmark: timing 100 iterations of no_xs, use_xs...
     no_xs:  0 wallclock secs ( 0.04 usr +  0.00 sys =  0.04 CPU) @ 2500.00/s (n=100)
            (warning: too few iterations for a reliable count)
    use_xs:  0 wallclock secs ( 0.04 usr +  0.01 sys =  0.05 CPU) @ 2000.00/s (n=100)
            (warning: too few iterations for a reliable count)
         Rate use_xs  no_xs
use_xs 2000/s     --   -20%
no_xs  2500/s    25%     --

0〜25%くらい速い傾向がある。

1000回

Benchmark: timing 1000 iterations of no_xs, use_xs...
     no_xs:  1 wallclock secs ( 0.46 usr +  0.07 sys =  0.53 CPU) @ 1886.79/s (n=1000)
    use_xs:  1 wallclock secs ( 0.45 usr +  0.05 sys =  0.50 CPU) @ 2000.00/s (n=1000)
         Rate  no_xs use_xs
no_xs  1887/s     --    -6%
use_xs 2000/s     6%     --

もうほとんど変わらない。ほんのり速くなる程度です。
ただ1000回も繰り返すシーンってのが微妙なので、参考にならないかも。

結論

もともとはドラスティックな展開を期待しすぎないようにって事だったけど、
やりとりするデータ量が大きくなるほど、パフォーマンス向上の期待が持てるモジュールってのが分かりました。

*1:今は1.24