Subscribed unsubscribe Subscribe Subscribe

memcachedにlat,lon2つを取得するのとgeohashとかにして一つ取得してデコードするのどっちが早いのか

memcachedにlat,lon2つを取得するのとgeohashとかにして一つ取得してデコードするのどっちが早いのか気になったので調べてみた

use strict;
use warnings;

use Benchmark qw/:all/;
use Cache::Memcached::Fast;
use Geo::Hash::XS;
use Geo::Hash;

my $memd = Cache::Memcached::Fast->new({
        servers => ["localhost:11211"]
});
$memd->flush_all;

my $total = 1000;

my $geohash_xs = Geo::Hash::XS->new;

for ( my $i = 0; $i < $total; $i++ ) {
    my $lat = rand(180) - 90;
    my $lon = rand(360) - 180;
    $memd->set("lat$i", $lat);
    $memd->set("lon$i", $lon);
    $memd->set("hash10_$i", $geohash_xs->encode( $lat, $lon, 10 ) );
    $memd->set("hash20_$i", $geohash_xs->encode( $lat, $lon, 20 ) );
    $memd->set("hash30_$i", $geohash_xs->encode( $lat, $lon, 30 ) );
}

cmpthese 300 , {
    latlon => sub {
        for ( my $i = 0; $i < $total; $i++ ) {
            my $lat = $memd->get("lat$i");
            my $lon = $memd->get("lon$i");
        }
    },
    geohash => sub {
        for ( my $i = 0; $i < $total; $i++ ) {
            my $hash = $memd->get("hash10_$i");
        }
    },
    geohash_xs_decode_10 => sub {
        my $geohash = Geo::Hash::XS->new;
        for ( my $i = 0; $i < $total; $i++ ) {
            my ($lat, $lon) = $geohash->decode($memd->get("hash10_$i"));
        }
    },
    geohash_xs_decode_20 => sub {
        my $geohash = Geo::Hash::XS->new;
        for ( my $i = 0; $i < $total; $i++ ) {
            my ($lat, $lon) = $geohash->decode($memd->get("hash20_$i"));
        }
    },
    geohash_xs_decode_30 => sub {
        my $geohash = Geo::Hash::XS->new;
        for ( my $i = 0; $i < $total; $i++ ) {
            my ($lat, $lon) = $geohash->decode($memd->get("hash30_$i"));
        }
    },
    geohash_pure_decode => sub {
        my $geohash = Geo::Hash->new;
        for ( my $i = 0; $i < $total; $i++ ) {
            my ($lat, $lon) = $geohash->decode($memd->get("hash10_$i"));
        }
    }
};

こんなスクリプトで

                       Rate geohash_pure_decode latlon geohash_xs_decode_30 geohash_xs_decode_20 geohash_xs_decode_10 geohash
geohash_pure_decode  8.19/s                  --   -56%                 -76%                 -76%                 -77%    -79%
latlon               18.6/s                127%     --                 -46%                 -46%                 -47%    -53%
geohash_xs_decode_30 34.3/s                319%    85%                   --                   0%                  -2%    -13%
geohash_xs_decode_20 34.3/s                319%    85%                   0%                   --                  -2%    -13%
geohash_xs_decode_10 35.1/s                328%    89%                   2%                   2%                   --    -11%
geohash              39.5/s                382%   113%                  15%                  15%                  13%      --

な結果になった。Geo::Hash::XSを使えば些細かもしれないけれど、2つ持ってくるよりは一つにまとめた方が早いらしい。
kyotocabinetでやったら呼び出しが最適化されてるのか、decodeの方が41%早いだけにとどまった。

ちなみにセットするのも

                       Rate geohash_pure_encode latlon geohash_xs_encode_30 geohash_xs_encode_20 geohash_xs_encode_10
geohash_pure_encode  2.98/s                  --   -82%                 -90%                 -90%                 -91%
latlon               16.7/s                458%     --                 -45%                 -45%                 -47%
geohash_xs_encode_30 30.3/s                914%    82%                   --                  -0%                  -4%
geohash_xs_encode_20 30.4/s                919%    82%                   0%                   --                  -4%
geohash_xs_encode_10 31.7/s                962%    90%                   5%                   4%                   --

なのでencodeして一回で入れたほうが早い。