Masteries

技術的なことや仕事に関することを書いていきます.

PerlのJSONとJSON::PPとJSON::XSと

結論

JSON::XSが既にインストールされているなら, 明示的にJSON::XSを使わず, JSONを使ったとしても, あまり速度は変わらない.

JSONとJSON::PPとJSON::XS

PerlでJSONを扱う時に使えるモジュールの1つがJSONモジュールです.

metacpan.org

JSONモジュールは, 実際にJSONをdecode/encodeする処理を差し替えることができます. デフォルトではPure Perl実装のJSON::PPが使われ, インストール済みで利用が可能であればXSを使って実装されたより高速なJSON::XSを使うようになっています.

metacpan.org

metacpan.org

JSON (+ JSON::XS) vs JSON::XS

JSON::PPとJSON::XSなら, 当然JSON::XSを使う方が高速です. では, JSONとJSON::XSならどうでしょう. JSON::XSがインストール済みなら, JSONでもJSON::XSを使ってdecode/encodeをするはずですが, 実はそれ以外の処理があったりして, JSON::XSを直接使う方が早い... ということはないのでしょうか?

use strict;
use warnings;

use Benchmark qw/timethese cmpthese/;

use JSON ();
use JSON::PP ();
use JSON::XS ();

my $result = timethese(10000000, {
    json => sub {
        JSON::encode_json({a => 1});
    },
    xs => sub {
        JSON::XS::encode_json({a => 1});
    },
    pp => sub {
        JSON::PP::encode_json({a => 1});
    },
});

cmpthese $result;

というわけでさっくりベンチを取ると...

perl bench.pl
Benchmark: timing 10000000 iterations of json, pp, xs...
      json:  3 wallclock secs ( 1.96 usr +  0.02 sys =  1.98 CPU) @ 5050505.05/s (n=10000000)
        pp: 25 wallclock secs (24.03 usr +  0.13 sys = 24.16 CPU) @ 413907.28/s (n=10000000)
        xs:  3 wallclock secs ( 2.02 usr +  0.02 sys =  2.04 CPU) @ 4901960.78/s (n=10000000)
          Rate    pp    xs  json
pp    413907/s    --  -92%  -92%
xs   4901961/s 1084%    --   -3%
json 5050505/s 1120%    3%    --

...JSON::PPとの差は歴然ですが, JSON::XSと(内部でJSON::XSを使っている)JSONの間には, あんまり差はないですね.

余談

ちなみに, JSONモジュールは PERL_JSON_BACKEND モジュールで利用する実装を指定することができます. 例えば, PERL_JSON_BACKEND=JSON::PP として, 先程のスクリプトを実行すると...

$ PERL_JSON_BACKEND=JSON::PP perl bench.pl
Benchmark: timing 10000000 iterations of json, pp, xs...
      json: 23 wallclock secs (23.85 usr +  0.25 sys = 24.10 CPU) @ 414937.76/s (n=10000000)
        pp: 24 wallclock secs (24.10 usr +  0.22 sys = 24.32 CPU) @ 411184.21/s (n=10000000)
        xs:  3 wallclock secs ( 2.08 usr +  0.01 sys =  2.09 CPU) @ 4784689.00/s (n=10000000)
          Rate    pp  json    xs
pp    411184/s    --   -1%  -91%
json  414938/s    1%    --  -91%
xs   4784689/s 1064% 1053%    --

先程と違ってJSONはJSON::PPを使っているので, JSON::XS > JSON::PP = JSON, という結果になりました.