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
950
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
2k
ftp.jaist.ac.jpの低レイヤーの話
kfujieda
0
78
Other Decks in Programming
See All in Programming
REST API設計の実践 – ベストプラクティスとその落とし穴
kentaroutakeda
2
320
『Python → TypeScript』オンボーディング奮闘記
takumi_tatsuno
1
140
テスト分析入門/Test Analysis Tutorial
goyoki
12
2.7k
External SecretsのさくらProvider初期実装を担当しています
logica0419
0
240
Babylon.js 8.0のアプデ情報を 軽率にキャッチアップ / catch-up-babylonjs-8
drumath2237
0
110
Rethinking Data Access: The New httpResource in Angular
manfredsteyer
PRO
0
220
Cloudflare Realtime と Workers でつくるサーバーレス WebRTC
nekoya3
0
240
TypeScript を活かしてデザインシステム MCP を作る / #tskaigi_after_night
izumin5210
4
480
TypeScript エンジニアが Android 開発の世界に飛び込んだ話
yuisakamoto
6
960
人には人それぞれのサービス層がある
shimabox
3
470
Parallel::Pipesの紹介
skaji
2
870
がんばりすぎないコーディングルール運用術
tsukakei
1
180
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
245
12k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Embracing the Ebb and Flow
colly
85
4.7k
A better future with KSS
kneath
239
17k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.6k
Navigating Team Friction
lara
186
15k
For a Future-Friendly Web
brad_frost
178
9.7k
Gamification - CAS2011
davidbonilla
81
5.3k
Unsuck your backbone
ammeep
671
58k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
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