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
860
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
69
Other Decks in Programming
See All in Programming
watsonx.ai Dojo #4 生成AIを使ったアプリ開発、応用編
oniak3ibm
PRO
1
100
Outline View in SwiftUI
1024jp
1
330
Contemporary Test Cases
maaretp
0
140
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
230
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
EventSourcingの理想と現実
wenas
6
2.3k
cmp.Or に感動した
otakakot
2
150
Arm移行タイムアタック
qnighy
0
320
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
距離関数を極める! / SESSIONS 2024
gam0022
0
280
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
50
7.2k
Side Projects
sachag
452
42k
Keith and Marios Guide to Fast Websites
keithpitt
409
22k
It's Worth the Effort
3n
183
27k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Designing Experiences People Love
moore
138
23k
Automating Front-end Workflow
addyosmani
1366
200k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Unsuck your backbone
ammeep
668
57k
The Pragmatic Product Professional
lauravandoore
31
6.3k
Transcript
NaN BoxingによるJSON パーサーの高速化 藤枝 和宏 twitter: kfujieda
[email protected]
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