C#用の速いJSONパーザーを書いてみた

DynaJsonというC#用のJSONパーザーを書いてみた。

DynamicJsonと完全互換でMITライセンスでずっと速くて小さいパーザーがほしかったけど、そんなものはないので自分で書いた。

何かのAPIのレスポンスを処理するときにDynamicJsonはとても便利である。パーズすると動的オブジェクトが返り、JSONのメンバーをメンバーアクセス演算子.で参照できる。

var json = DynamicJson.Parse(@"{  
    ""foo"": ""json"",  
    ""bar"": [100,200],  
    ""nest"": {""foobar"": true}  
}");  
var a1 = json.foo; // "json"  
var a2 = json.nest.foobar; // true  

そしてDynamicJsonは、たった431行のソースコードで実装されている。.NETにはJsonReaderWriterFactoryというJSONとXMLと相互変換するクラスがあって、それを巧妙に利用することでこのサイズに収まっている。

問題はライセンスがMs-PLであるためGPLで使えないことと、遅いこと。

DynamicJsonのようにメンバーアクセス演算子.でJSONを参照できるJSONパーザーは、他にJilNewtonsoft.Jsonがある。これらはMITライセンスだけど、ファイルサイズがすごく大きいし、それほど速くない。また、メンバーアクセス以外の動的オブジェクトの仕様が違うので、DynamicJsonと置き換える形では使えない。

そこで要件を満たすものを自分で書いたのがDynaJsonである。

ベンチマークの結果を見てもらえればわかるけど、だいぶ速いのができた。自分の用途では、大きなJSON文字列のパーズさえ速ければ、それ以外はどうでもよかったけど、ついでにほかも高速化した。

なぜ速いかは書いたけど、それ以外に表引きや番兵で条件分岐をホットパスから取り除く古典的なやりかたが1割くらい性能に寄与している。ほかのパーザーも、そういうのていねいにやったらもっと速くなるんじゃないかなあ。