結論
JSON::XSが既にインストールされているなら, 明示的にJSON::XSを使わず, JSONを使ったとしても, あまり速度は変わらない.
JSONとJSON::PPとJSON::XS
PerlでJSONを扱う時に使えるモジュールの1つがJSONモジュールです.
JSONモジュールは, 実際にJSONをdecode/encodeする処理を差し替えることができます. デフォルトではPure Perl実装のJSON::PPが使われ, インストール済みで利用が可能であればXSを使って実装されたより高速なJSON::XSを使うようになっています.
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, という結果になりました.