Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NaN BoxingによるJSONパーサーの高速化
Search
Kazuhiro Fujieda
February 14, 2020
Programming
2
910
NaN BoxingによるJSONパーサーの高速化
DynaJsonの高速化で使っているNaN Boxingという技術を紹介する。
Kazuhiro Fujieda
February 14, 2020
Tweet
Share
More Decks by Kazuhiro Fujieda
See All by Kazuhiro Fujieda
静的クラスは遅いことがあるよ
kfujieda
3
1.9k
ftp.jaist.ac.jpの低レイヤーの話
kfujieda
0
70
Other Decks in Programming
See All in Programming
AIレビュー導入によるCIツールとの共存と最適化
kamo26sima
1
630
ML.NETで始める機械学習
ymd65536
0
240
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
7
4.2k
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
1.2k
Webフレームワークとともに利用するWeb components / JSConf.jp おかわり
spring_raining
1
130
color-scheme: light dark; を完全に理解する
uhyo
7
510
もう少しテストを書きたいんじゃ〜 #phpstudy
o0h
PRO
21
4.3k
TCAを用いたAmebaのリアーキテクチャ
dazy
0
220
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.6k
新宿駅構内を三人称視点で探索してみる
satoshi7190
2
130
SwiftUI Viewの責務分離
elmetal
PRO
2
280
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
14
4.8k
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
GraphQLの誤解/rethinking-graphql
sonatard
69
10k
KATA
mclloyd
29
14k
Scaling GitHub
holman
459
140k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Documentation Writing (for coders)
carmenintech
68
4.6k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.5k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
30
4.6k
Making Projects Easy
brettharned
116
6k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Agile that works and the tools we love
rasmusluckow
328
21k
Transcript
NaN BoxingによるJSON パーサーの高速化 藤枝 和宏 twitter: kfujieda fujieda@roundwide.com
DynaJson • https://github.com/fujieda/DynaJson/ • 高速なJSONパーサー • DynamicJson互換 var json =
JsonObject.Parse(@"{ ""foo"": ""json"", ""nest"": {""foobar"": true} }"); var a1 = json.foo; // "json" var a2 = json.nest.foobar; // true
速い citm_catalog.json (1.7MB)⇒DynamicObject 11.849 21.123 34.711 50.772 58.141 0 10
20 30 40 50 60 70 DynaJson Utf8Json Jil Newtonsoft.Json DynamicJson Time (ms) ←lower is better
なぜ速いか • JSONの値を16バイトの構造体に格納 • 動的メモリ割り当てが不要に • 代入でコピーが発生するが16バイトまでは速い
16バイトに格納する • Explicitレイアウトでフィールドを重ねる • doubleの上4バイトにJsonTypeを重ねる ⇒ NaN Boxing [StructLayout(LayoutKind.Explicit)] internal
struct InternalObject { [FieldOffset(4)] public JsonType Type; [FieldOffset(0)] public double Number; [FieldOffset(8)] public string String; [FieldOffset(8)] public JsonArray Array; [FieldOffset(8)] public JsonDictionary Dictionary; }
NaN Boxing • doubleのNaNの隙間に値を詰める • NaNは0/0などで発生する特別な値 • 表現は0xfff800000000 (qNANの場合) •
下位51ビットは任意の値でいい
NaNに値を詰める enum JsonType : uint { Null = 0xfff80001, True
= 0xfff80002, False = 0xfff80003, String = 0xfff80004, Array = 0xfff80005, Object = 0xfff80006 } static object ToValue(InternalObject obj) { switch (obj.Type) { case JsonType.Null: return null; case JsonType.True: return true; case JsonType.False: return false; case JsonType.String: return obj.String; case JsonType.Array: case JsonType.Object: return new JsonObject(obj); default: return obj.Number; } }
NaN Boxingの効果 11.849 13.418 16.294 0 5 10 15 20
struct 16 struct 24 class Time (ms) ←lower is better