json encoder/decoder
#idea
VM/JIT/コード生成で実装する
一般にクロージャの連鎖は遅い(関数呼び出しが遅いため)
関数型言語だとコンビネータを多用するので最適化に気合が入っていて普通に速いこともある
JITであればPCを進めるだけ、VMであればポインタを付け替えるだけで済む
速い itoa/atoi/dtoa/atod を使う
10進文字列を高速に整数に変換するみたいな
Encoder
構造体に対応するデータに各フィールドのキーをあらかじめエンコードしておく
毎回エスケープするか?とかチェックしない
"{key}":を持っておくのが理想
値の後ろにカンマを付けておく
まとめて書き出して境界チェックや命令数を削減できる
OpStructEndが}を、OpFieldEndが,を書くかわりにOpStructEndが後ろの,に},を上書きする
インデントのある世界でもOpIndentStructEndが\n\t\t...},を上書きする
インデントや色があるときに速い必要はないけど実装を使い回せて便利
バッファを書き出すときに勢い余ってカンマまで書き出さないように注意
最大長が確定するフィールドを前に出してバッファの残りチェックを削減する
例えばuint64であれば20バイトあればエンコードできるので、これとキー名を合わせていくとどれだけあれば拡張が起きずに追加できるかわかる
具体的には最大長はヘッダ長+最大長ありフィールドのキー部長さ+フィールドの最大長+最初の最大長なしフィールドのキー部長さ
常にそんな使うわけではない(用途によるけどだいたいintだったら5文字超えることはあんまりない)ので、最大長が長くなりそうだったら適当なところで明示的にOpFlushを挿入して残りチェックをする
JSON 以外でも使えるはず、Protobuf とか
Decoder
構造体のフィールド探索を Trie にする
FYI: neue cc - MessagePack for C#におけるオートマトンベースの文字列探索によるデシリアライズ速度の高速化
Folding...? 知らない子ですね
読み出しバッファの後ろを\0で埋める
絶対に出現しない文字なので境界チェックなしで止めることができる
FYI : 最速のJSONライブラリを求めて - Speaker Deck
バイト単位で読む実装なら1つ付ける、SWAR するなら8つとか
受け取ったバッファの後ろに入れられそうならそうする。できないならストリームにフォールバックか