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
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
270
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
1.1k
Unity Android XR入門
sakutama_11
0
180
color-scheme: light dark; を完全に理解する
uhyo
7
500
Better Code Design in PHP
afilina
0
180
Honoとフロントエンドの 型安全性について
yodaka
7
1.5k
複数のAWSアカウントから横断で 利用する Lambda Authorizer の作り方
tc3jp
0
120
CDK開発におけるコーディング規約の運用
yamanashi_ren01
2
260
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
9
2.5k
バッチを作らなきゃとなったときに考えること
irof
2
540
機能が複雑化しても 頼りになる FactoryBotの話
tamikof
1
220
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
14
4.7k
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
336
57k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
Being A Developer After 40
akosma
89
590k
Speed Design
sergeychernyshev
27
810
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Navigating Team Friction
lara
183
15k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.4k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
27
1.9k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
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