« 几种压缩算法对比 | (回到Blog入口) | LWP的HTTP请求突然不能用的问题 »

几种perl持久化速度比较

 前段时间看到一个老外对perl网络传输持久化做了个对比,原文地址http://blog.celogeek.com/201401/519/perl-benchmark-jsonxs-vs-sereal-vs-datamessagepack/,需要自己翻墙。

本人在自己的机器上也做了下测试。硬件配置Intel(R) Xeon(R) CPU           X3430  @ 2.40GHz, 8G内存,Centos6.4 64位 perl 5.10 64位。

原文中作者测试了Data::MessagePack,Sereal,JSON,CBOR,这里我也加了一个Storable,毕竟从取材来说这个模块是自带的。注意CBOR目前只支持64位的操作系统。以下是测试结果

测试小数据的结果

{

    CBOR          {

        decode   809562,

        encode   1720319,

        size     30

    },

    JSON          {

        decode   669260,

        encode   860160,

        size     42

    },

    MP            {

        decode   573439,

        encode   491519,

        size     30

    },

    Sereal        {

        decode   595284,

        encode   600178,

        size     38

    },

    'Sereal OO'   {

        decode   764586,

        encode   1181633,

        size     38

    },

    storable      {

        decode   312785,

        encode   46109

    }

}

我们可以看到序列化和反序列化最快的是CBOR,而storable则全部垫底,我们在来测试比数据比较大的结果
 Result : 
{
    CBOR          {
        decode   22635,
        encode   45271,
        size     2757
    },
    JSON          {
        decode   15017,
        encode   26880,
        size     3941
    },
    MP            {
        decode   16541,
        encode   40959,
        size     2653
    },
    Sereal        {
        decode   17919,
        encode   81919,
        size     2902
    },
    'Sereal OO'   {
        decode   17919,
        encode   86015,
        size     2902
    },
    storable      {
        decode   14335,
        encode   14037
    }
}
 
Sereal的序列化速度第一,而且相差不是一两点的,而反序列化则是CBOR领先,storable再次完败。
 
总体来说CBOR性能确实很强,但是作为一个新兴的持久化方式来说各种语言的支持才是最麻烦的。
Sereal则各方面都比较突出,而且很多语言也都支持。
JSON就不用说了,基本上web上到处都能见到,性能比前面2个要弱一些
Data::MessagePack我没具体了解,但从测试结果上看也算是一种备选方案
也许Storable的唯一优势就是随perl自带吧。
 
以下是测试代码:
#!perl
use 5.010;
use DDP;
use Data::MessagePack;
use Sereal;
use JSON;
#use JSON::XS;
use CBOR::XS;
use Storable qw(nstore store_fd nstore_fd freeze thaw dclone);
use Benchmark qw/countit :hireswallclock/;
 
my $dt = Data::MessagePack->new;
my $se = Sereal::Encoder->new({no_shared_hashkeys => 1}); # may lead to high size, but 100% faster at encoding !
my $sd = Sereal::Decoder->new;
my $cb = CBOR::XS->new;
 
sub count_this {
    my ($label, $meth, $storage) = @_;
 
    $|=1;
    print $label, " ";
    $$storage = countit(1, $meth)->iters;
    print ".";
    $$storage += countit(1, $meth)->iters;
    print ".";
    $$storage += countit(1, $meth)->iters;
    say ".";
    $$storage = int($$storage / 3);
}
 
sub run_bench {
    my ($label, $struct) = @_;
 
    my $ser_sereal = Sereal::encode_sereal($struct);
    my $ser_sereal_oo = $se->encode($struct);
    my $ser_mp = $dt->pack($struct);
    my $ser_json = JSON::encode_json($struct);
    my $ser_cb = $cb->encode($struct);
    my $ser_storable = freeze $struct;
 
    my %result = (
        'Sereal' => { size => length($ser_sereal) },
        'Sereal OO' => { size => length($ser_sereal_oo) },
        'MP' => { size => length($ser_mp) },
        'JSON' => { size => length($ser_json) },
        'CBOR' => { size => length($ser_cb) },
        'Storable' => { size => length($ser_storable) },
    );
 
    say "Start benchmark for $label ...";
    count_this('Sereal Decode'   , sub {Sereal::decode_sereal($ser_sereal)}, \$result{Sereal}{decode});
    count_this('Sereal Encode'   , sub {Sereal::encode_sereal($struct)}    , \$result{Sereal}{encode});
    count_this('Sereal OO Decode', sub {$sd->decode($ser_sereal_oo)}       , \$result{'Sereal OO'}{decode});
    count_this('Sereal OO Encode', sub {$se->encode($struct)}              , \$result{'Sereal OO'}{encode});
    count_this('MP Decode'       , sub {$dt->unpack($ser_mp)}              , \$result{'MP'}{decode});
    count_this('MP Encode'       , sub {$dt->pack($struct)}                , \$result{'MP'}{encode});
    count_this('JSON Decode'     , sub {JSON::decode_json($ser_json)}      , \$result{'JSON'}{decode});
    count_this('JSON Encode'     , sub {JSON::encode_json($struct)}        , \$result{'JSON'}{encode});
    count_this('CBOR Decode'     , sub {$cb->decode($ser_cb)}              , \$result{'CBOR'}{decode});
    count_this('CBOR Encode'     , sub {$cb->encode($struct)}              , \$result{'CBOR'}{encode});
    count_this('storable Encode'     , sub {freeze $struct}              , \$result{'storable'}{encode});
    count_this('storable Decode'     , sub {thaw $ser_storable}              , \$result{'storable'}{decode});
    say "Finish benchmark for $label ...";
    say "Result : ";
    say p(%result);
 
}
 
run_bench( 'small', { a => 1, b => 2, c => 3, d => 'string', e => 5.018 } );
run_bench( 'large', { a => 1, b => 2, c => 3, d => 'string', e => 5.018, f => [map{$_} 1..1000] } );
 

引用通告

TrackBack URL for this entry:
如果您想引用这篇文章到您的Blog,
请复制下面的链接,并放置到您发表文章的相应界面中。
http://playcat.net/mt-tb.cgi/117

发表一个评论

(如果你此前从未在此 Blog 上发表过评论,则你的评论必须在 Blog 主人验证后才能显示,请你耐心等候。)

关于

此页面包含了发表于2014年8月22日 14:57的 Blog 上的单篇日记。

此 Blog 的前一篇日记是 几种压缩算法对比

此 Blog 的后一篇日记是 LWP的HTTP请求突然不能用的问题

更多信息可在 主索引 页和 归档 页看到。

Creative Commons License
此 Blog 中的日记遵循以下授权 Creative Commons(创作共用)授权.
Powered by
Movable Type 6.3.2