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
920
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
74
Other Decks in Programming
See All in Programming
リアクティブシステムの変遷から理解するalien-signals / Learning alien-signals from the evolution of reactive systems
yamanoku
3
1.2k
SEAL - Dive into the sea of search engines - Symfony Live Berlin 2025
alexanderschranz
1
130
MCP調べてみました! / Exploring MCP
uhzz
2
2.2k
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
ssssota
1
1.4k
remix + cloudflare workers (DO) docker上でいい感じに開発する
yoshidatomoaki
0
130
英語 × の私が、生成AIの力を借りて、OSSに初コントリビュートした話
personabb
0
180
Going Structural with Named Tuples
bishabosha
0
200
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
840
[NG India] Event-Based State Management with NgRx SignalStore
markostanimirovic
1
110
State of Namespace
tagomoris
4
750
データベースエンジニアの仕事を楽にする。PgAssistantの紹介
nnaka2992
9
4.5k
Bedrock×MCPで社内ブログ執筆文化を育てたい!
har1101
6
900
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
104
19k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Code Review Best Practice
trishagee
67
18k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
135
33k
Unsuck your backbone
ammeep
670
57k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.1k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Into the Great Unknown - MozCon
thekraken
37
1.7k
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