Hatena::ブログ(Diary)

Yet Another Hackadelic

2007-07-18 今空前の収支報告ブーム

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

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

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

激しく既出だった。(d:id:spiritloose:20060909:1157767723)

id:spiritlooseさんとやりたい方向性がかなり被ってるなぁ。w

あと、

新しいbinary protocol使えばもっと差が出るかも miyagawaのブックマーク / 2007年09月11日

むむ!後で調べる。

前置き

ちなみに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

2007-07-16

memcachedのrpmをFedora用に作る

実のところmemcachedはsvn trunkに既にspecファイルが存在します。

http://code.sixapart.com/svn/memcached/trunk/server/memcached.spec

しかしこれはFedoraではrpmbuild出来ません。*1

Dagのmemcachedspecファイルがあるので、そいつを持ってきます。

# cd /usr/src/redhat/SOURCES/
# wget http://www.danga.com/memcached/dist/memcached-1.2.2.tar.gz
# cd ../SPECS
# wget http://dag.wieers.com/rpm/packages/memcached/memcached.spec
# rpmbuild -bb memcached.spec

これで /usr/src/redhat/RPMS/{$ARCH} 辺りにrpmが出来上がります。

*1:%installのinitスクリプトの部分がおかしいのと%post時にchkconfig対応してないと怒られる