逆襲のJSONIC! ……ならず
某所にてJSONICなんて目じゃないぜ、とばかりにJacksonに圧倒的差を付けられてしまい涙目状態だったわけですが、ちょっとはがんばってみようというわけで今日一日かけてパフォーマンス・チューニングしてみました。
チューニング結果は次の通り(ソースはリンク先とほぼ同じ。チューニング後のものは、jsonic-2.5 ベータ1としてsourceforgeアップしました)。
- | Jackson | JSONIC | 速度比 |
---|---|---|---|
Map1000×List1000 | 408.53354 | 1633.88864 | 1 : 4.00 |
Map1000×List10000 | 4226.438111 | 17875.302405 | 1 : 4.23 |
Map10000×List1000 | 4216.586653 | 17389.64673 | 1 : 4.12 |
Map100×Object | 55.739099 | 29.20877 | 1 : 0.52 |
Map1K×Object | 13.22453 | 27.175345 | 1 : 2.05 |
Map10K×Object | 39.323709 | 103.618247 | 1 : 2.64 |
Map100K×Object | 277.424284 | 1665.091483 | 1 : 6.00 |
List100×Object | 4.21741 | 1.085577 | 1 : 0.26 |
List1K×Object | 5.713606 | 7.983138 | 1 : 1.40 |
List10K×Object | 23.862154 | 83.53123 | 1 : 3.50 |
List100K×Object | 216.342847 | 797.925343 | 1 : 3.69 |
うーむ、JSONICは10倍遅い! とは言われなくなっても、4倍遅いは言われかねない数字です。逆襲失敗。まぁ、オブジェクト数が数千以下だとJSONICの方が速かったりするみたいなのでWeb開発の実用上は問題ない気もしますが。
ちなみに、JSONICもjson-libやgsonに比べれば3倍以上高速なので、JSONICが遅いというよりJacksonが速すぎるという噂もあります。実際、ToStringに匹敵する速度で動作してます。Jacksonのソースもちょっと見てみたりしたのですが、なぜこんなに早いのかまったくの謎。文字列操作で工夫しているような雰囲気も見えますが、特に項目数が多いときの速度は説明が付かないレベル。謎すぎる。
続・逆襲のJSONIC! ……まだまだ駄目です。
引き続き遅そうなところを調査した結果、どうもAppendableが悪さをしているような雰囲気。Appendableの各メソッドはCharSequenceになっているものの、CharSequenceは配列コピー系のメソッドがなく、JDK付属のStringBuilderのソースを読むと instanceof で分岐しまくっている。普段使うときは、Appendableではなく、StringBuilderやWriterのStringを引数に取るメソッドが使われているので、その分の速度差が発生しているらしい。
というわけで、その部分を修正した結果です。
[追記] 微妙にObject型の変換が速くなったので結果を貼り替えました。
- | Jackson | JSONIC | 速度比 |
---|---|---|---|
Map1000×List1000 | 381.1315 | 800.7116 | 1: 2.10 |
Map1000×List10000 | 3796.3256 | 8079.5918 | 1: 2.13 |
Map10000×List1000 | 3822.6797 | 8478.6999 | 1: 2.22 |
Map100×Object | 47.9895 | 16.1057 | 1: 0.34 |
Map1K×Object | 10.8506 | 13.1638 | 1: 1.21 |
Map10K×Object | 30.3012 | 59.0540 | 1: 1.95 |
Map100K×Object | 237.7610 | 1057.1882 | 1: 4.45 |
List100×Object | 2.6117 | 0.7956 | 1: 0.30 |
List1K×Object | 4.4467 | 5.3637 | 1: 1.21 |
List10K×Object | 20.4574 | 41.2442 | 1: 2.02 |
List100K×Object | 187.5207 | 413.8793 | 1: 2.21 |
だいたい2倍くらいの遅さに収まってきました。相変わらずオブジェクト数が増加すると速度が悪化する状況は変わらず、という感はあります。これ以上の高速化は難しそうなのだが、どうすればよいのか。
Map×Listのケースの速度差は、ほとんど文字列の変換速度の違いでMapやListの変換速度自体はほとんど変わらないと思う。でも文字列の変換もかなり最適化しているので、何が原因でこの差がでているのかは良くわからない。