Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
NaN BoxingによるJSONパーサーの高速化
Kazuhiro Fujieda
February 14, 2020
Programming
2
630
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.6k
ftp.jaist.ac.jpの低レイヤーの話
kfujieda
0
45
Other Decks in Programming
See All in Programming
dbtとBigQueryで始めるData Vault入門
kazk1018
0
200
Reactでアプリケーションを構築する多様化
sakito
4
3.5k
CIでAndroidUIテストの様子を録画してみた
mkeeda
0
190
[RailsConf 2022] The pitfalls of realtime-ification
palkan
0
350
NieR Re[in]carnationにおけるUnityアニメーション活用術
applibot
1
900
ソフトウェアテストなんて他人事! だと思っていた私が始めた小さな取り組み
izumii19
0
390
Unboxing Rails 7
claudiob
1
120
偏見と妄想で語るスクリプト言語としての Swift / Swift as a Scripting Language
lovee
2
300
ebpfとWASMに思いを馳せる2022 / techfeed-conference-2022-ebpf-wasm-amsy810
masayaaoyama
0
770
コードの解析と言語習得の心得
jinjin33333
0
130
Licences open source : entre guerre de clochers et radicalité
pylapp
2
360
不具合に立ち向かう テスト戦略 ~ NestJSで作るCI環境 ~
naoki_haba
0
130
Featured
See All Featured
Faster Mobile Websites
deanohume
294
28k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
100
5.9k
YesSQL, Process and Tooling at Scale
rocio
157
12k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
349
27k
Fireside Chat
paigeccino
11
1.3k
How GitHub Uses GitHub to Build GitHub
holman
465
280k
Typedesign – Prime Four
hannesfritz
33
1.3k
Git: the NoSQL Database
bkeepers
PRO
415
59k
Pencils Down: Stop Designing & Start Developing
hursman
112
9.8k
Building an army of robots
kneath
299
40k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
103
16k
Producing Creativity
orderedlist
PRO
333
37k
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