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
静的クラスは遅いことがあるよ
Search
Kazuhiro Fujieda
July 29, 2020
Technology
2.1k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
静的クラスは遅いことがあるよ
Kazuhiro Fujieda
July 29, 2020
More Decks by Kazuhiro Fujieda
See All by Kazuhiro Fujieda
NaN BoxingによるJSONパーサーの高速化
kfujieda
2
1k
ftp.jaist.ac.jpの低レイヤーの話
kfujieda
0
97
Other Decks in Technology
See All in Technology
やさしいA2A入門
minorun365
PRO
7
820
Mastering Ruby Box
tagomoris
3
150
Rubyで音を視る
ydah
1
190
個人最適 から 全体最適 へ AI情報共有会・AIギルド・AI-DLC で進める カンリーの組織展開
rfdnxbro
0
2k
Reliability in the Age of AI: Engineering for AI Velocity
rrreeeyyy
0
110
[モダンアプリ勉強会]今更聞けないGit/GitHub入門
tsukuboshi
0
310
Dario Amodi『Policy on the AI Exponential』を理解する
nagatsu
0
210
Dynamic Workersについて
yusukebe
2
640
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
5
1.8k
AI Testing Talks: Challenges of Applying AI in Software Testing: From Hype to Practical Use
exactpro
PRO
1
140
Agentic Defenseとともにセキュリティエンジニアが輝き続けるには / How Security Engineers Can Keep Excelling with Agentic Defense
yuj1osm
0
130
あなたの AI ワークスペースに、 専門コーダーを連れてくる - Amazon Quick Desktop 最新情報
kawaji_scratch
1
120
Featured
See All Featured
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
430
Making Projects Easy
brettharned
120
6.7k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
360
For a Future-Friendly Web
brad_frost
183
10k
KATA
mclloyd
PRO
35
15k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
240
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Site-Speed That Sticks
csswizardry
13
1.2k
How STYLIGHT went responsive
nonsquared
100
6.2k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Transcript
静的クラスは遅いことが あるよ 藤枝 和宏 twitter: kfujieda
[email protected]
DynaJson • https://github.com/fujieda/DynaJson/ • 高速なJSONパーザー • DynamicJson互換 dynamic json =
JsonObject.Parse(@"{ ""foo"": ""json"", ""nest"": {""foobar"": true} }"); string a1 = json.foo; // "json" bool a2 = json.nest.foobar; // true
速い citm_catalog.json (1.7MB)をパーズ .NET Core 3.1 Ubuntu 18.04 on Azure
D2ds_v4 0 5 10 15 20 25 30 35 40 DynaJson Utf8Json Jil Newtonsoft.Json DynamicJson Time (ms) ←lower is better
静的クラスを避ける public class JsonParser { private static readonly JsonParser Instance
= new JsonParser(); // インスタンスは一つ public static object Parse(TextReader reader, int maxDepth) { return Instance.ParseInternal(reader, maxDepth); // インスタンスメソッドを呼ぶ } private object ParseInternal(TextReader reader, int maxDepth) { // パーザーの本体 } }
静的クラスは遅い なぜか遅い 0 2 4 6 8 10 12 14
Static Normal Time (ms) ←lower is better .NET Core 3.1 Ubuntu 18.04 on Azure D2ds_v4
ディスアセンブルしてみる .NET Core 3.1.6 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.31603), X64 RyuJIT
JsonParser.ParseJsonInternal() ... mov r9d,[rbp+24] inc r9d mov [rbp+24],r9d inc dword ptr [rbp+28] cmp [rbp+20],r9d jne short M04_L01 ... Total bytes of code 7845 JsonParseStatic.Parse() ... mov r9d,[7FFE540EB864] inc r9d mov [7FFE540EB864],r9d inc dword ptr [7FFE540EB868] cmp [7FFE540EB860],r9d jne short M02_L01 ... Total bytes of code 9701
中身の大きなループは遅い • DynaJsonのJsonParserは大きなループ • 中身が全部L1キャッシュに乗らないと遅い 1 2 3 4 5
6 7 8 プログラム L1キャッシュ 1 2 3 4 5 6 7 8 9 9
なぜコードが大きいのか インライン展開の多用 case 'n': CheckToken("ull"); value.Type = JsonType.Null; break; private
void CheckToken(string s) { Consume(); foreach (var ch in s) { if (ch != _nextChar) throw JsonParserException.ExpectingError($"'{ch}'", _position); Consume(); } } private void Consume() { _bufferIndex++; _position++; if (_available == _bufferIndex) { _bufferIndex = 0; _available = _reader.ReadBlock(_buffer, 0, _buffer.Length); if (_available == 0) { _isEnd = true; _nextChar = '¥0'; return; } } _nextChar = _buffer[_bufferIndex]; }
なぜコードが大きいのか インライン展開の多用 case 'n': CheckToken("ull"); value.Type = JsonType.Null; break; cmp
eax,6E ← 'n' jne near ptr M04_L104 mov r10d,[rbp+24] inc r10d mov [rbp+24],r10d inc dword ptr [rbp+28] cmp [rbp+20],r10d jne near ptr M04_L38 xor r9d,r9d mov [rbp+24],r9d mov rdx,[rbp+10] mov r9d,[rdx+8] mov rcx,[rbp+8] xor r8d,r8d mov rax,[rcx] mov rax,[rax+48] call qword ptr [rax+28] mov [rbp+20],eax cmp dword ptr [rbp+20],0 jne near ptr M04_L38 mov byte ptr [rbp+2E],1 mov word ptr [rbp+2C],0 M04_L08: mov r9,23E10009B48 mov rsi,[r9] xor edi,edi mov r12d,[rsi+8] test r12d,r12d jle short M04_L11 M04_L11: mov dword ptr [rsp+0B4],0FFF80001 jmp near ptr M04_L05 127 bytes
インライン展開をやめてみる • 差が縮まった • 静的クラスのキャッシュミスが減ったかな 0 2 4 6 8
10 12 14 16 Static (inlined) Normal (inlined) Static Normal Time (ms) ←lower is better
まとめ • 静的クラスはコードが大きくなることがある • 中身の大きすぎるループは遅くなることがある