encode_jsonメソッドの速度比較（JSON::PP , JSON::XS , Cpanel::JSON::XS）

# 概要
jsonにエンコードするモジュールの速度比較のアドバイスをいただいたので比較してみます。

# 比較するもの
- JSON::PP qw(encode_json);
- JSON::XS qw(encode_json);
- Cpanel::JSON::XS qw(encode_json);

# 方法
モジュール毎に５回テストを行います、最大値と最小値を除いた３回分の平均値で比較します。
１回のテストで50レコードのデータを50000回エンコードし、その速度が結果となります。
コードは以下です。
```perl
#!perl
use v5.40;
use JSON::PP qw(encode_json); #use JSON::XS qw(encode_json); #use Cpanel::JSON::XS qw(encode_json);
use utf8;
use Benchmark qw(timethese);

my @sum = (0, 0, 0);
my $d = [{a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"},
         {a=>1, b=>"テスト"}, {a=>1, b=>"試験"}, {a=>2, b=>"文字列"}, {a=>2, b=>"任意"}, {a=>3, b=>"仮文"}];

timethese(50000, {
   'Try1' => sub {encode_json($d)},
   'Try2' => sub {encode_json($d)},
   'Try3' => sub {encode_json($d)},
   'Try4' => sub {encode_json($d)},
   'Try5' => sub {encode_json($d)},
});

```

# 結果
## 集計
## 5回の試行結果の最大値と最小値を除いた3回の平均値
| モジュール | １秒当たり実行可能数 |
| -- | --: |
| JSON::PP | 3197.89回／秒 |
| JSON::XS | 78668.75回／秒 |
| Cpanel::JSON::XS | 88862.62回／秒 |

## 能力比較
| モジュール | JSON::PPを<br>1とすると | JSON::XSを<br>1とすると | Cpanel::JSON::XSを<br>1とすると |
| -- | --: | --: | --: |
| JSON::PP | 1.000 | 0.041 | 0.036 |
| JSON::XS | 24.600 | 1.000 | 0.885 |
| Cpanel::JSON::XS | 27.788 | 1.130 | 1.000 |

　Cpanel::JSON::XSはJSON::PPと比べて27.8倍も速く、またJSON::XSよりも1.13倍速いことがわかります。
　JSON::XSもJSON::PPと比べて24.6倍も速く明らかな速度の差が出ています。

## 検証端末
- CPU:Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
- MEMORY:32.0 GB
- OS:Windows11 Pro(24H2)
- Perl:StrawberryPerl 5.40.0.1

# まとめ
　これまで何も考えず標準モジュールのJSON::PPを利用してきましたが、JSON::XS、Cpanel::JSON::XSの速度を知り、C言語の力を感じました。
　今後は速度が必要な場合には採用することになりそうです。
　JSON::XS、Cpanel::JSON::XSを使ったことがなかったのでドキュメントを読んで特性を知りたいと思います。
　調査のきっかけをくださいました@mackee_wさんに感謝します。

# 資料：コードの出力結果
## JSON::PP->encode_json
```
Benchmark: timing 50000 iterations of Try1, Try2, Try3, Try4, Try5...
      Try1: 16 wallclock secs (15.72 usr +  0.01 sys = 15.73 CPU) @ 3177.83/s (n=50000)
      Try2: 16 wallclock secs (15.63 usr +  0.02 sys = 15.64 CPU) @ 3196.73/s (n=50000)
      Try3: 16 wallclock secs (15.61 usr +  0.00 sys = 15.61 CPU) @ 3203.07/s (n=50000)
      Try4: 16 wallclock secs (15.64 usr +  0.01 sys = 15.66 CPU) @ 3193.87/s (n=50000)
      Try5: 16 wallclock secs (15.56 usr +  0.05 sys = 15.61 CPU) @ 3203.28/s (n=50000)
```

## JSON::XS->encode_json
```
Benchmark: timing 50000 iterations of Try1, Try2, Try3, Try4, Try5...
      Try1:  1 wallclock secs ( 0.64 usr +  0.00 sys =  0.64 CPU) @ 78003.12/s (n=50000)
      Try2:  1 wallclock secs ( 0.64 usr +  0.00 sys =  0.64 CPU) @ 78003.12/s (n=50000)
      Try3:  0 wallclock secs ( 0.63 usr +  0.00 sys =  0.63 CPU) @ 80000.00/s (n=50000)
      Try4:  1 wallclock secs ( 0.64 usr +  0.00 sys =  0.64 CPU) @ 78003.12/s (n=50000)
      Try5:  1 wallclock secs ( 0.62 usr +  0.00 sys =  0.62 CPU) @ 80000.00/s (n=50000)
```

## Cpanel::JSON::XS->encode_json
```
Benchmark: timing 50000 iterations of Try1, Try2, Try3, Try4, Try5...
      Try1:  1 wallclock secs ( 0.56 usr +  0.02 sys =  0.58 CPU) @ 86505.19/s (n=50000)
      Try2:  0 wallclock secs ( 0.56 usr +  0.00 sys =  0.56 CPU) @ 88809.95/s (n=50000)
      Try3:  1 wallclock secs ( 0.56 usr +  0.00 sys =  0.56 CPU) @ 88809.95/s (n=50000)
      Try4:  1 wallclock secs ( 0.56 usr +  0.00 sys =  0.56 CPU) @ 88967.97/s (n=50000)
      Try5:  0 wallclock secs ( 0.55 usr +  0.00 sys =  0.55 CPU) @ 91407.68/s (n=50000)

```