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
GraphQL Ruby をちょっとだけ速くした / Make graphql-ruby fa...
Search
Fumiaki MATSUSHIMA
July 25, 2020
Programming
1
680
GraphQL Ruby をちょっとだけ速くした / Make graphql-ruby faster a bit
Kaigi on Rails new LT 発表資料
https://kaigionrails.doorkeeper.jp/events/109773
Fumiaki MATSUSHIMA
July 25, 2020
Tweet
Share
More Decks by Fumiaki MATSUSHIMA
See All by Fumiaki MATSUSHIMA
Learning from performance improvements on GraphQL Ruby
mtsmfm
1
1k
Ruby で作る Ruby (物理)
mtsmfm
1
180
GraphQL Ruby benchmark
mtsmfm
1
740
タイムアウトにご用心 / Timeout might break application state
mtsmfm
6
2.5k
Build REST API with GraphQL Ruby
mtsmfm
0
280
Gaming PC on GCP
mtsmfm
0
680
How to introduce GraphQL to an existing React-Redux application
mtsmfm
1
220
Canary release in StudySapuri
mtsmfm
0
2.9k
Analyze Rails CI
mtsmfm
2
800
Other Decks in Programming
See All in Programming
Symfony Mapper Component
soyuka
2
730
tidymodelsによるtidyな生存時間解析 / Japan.R2024
dropout009
1
790
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
130
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
3
420
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
220
[JAWS-UG横浜 #76] イケてるアップデートを宇宙いち早く紹介するよ!
maroon1st
0
460
創造的活動から切り拓く新たなキャリア 好きから始めてみる夜勤オペレーターからSREへの転身
yjszk
1
130
CSC305 Lecture 26
javiergs
PRO
0
140
わたしの星のままで一番星になる ~ 出産を機にSIerからEC事業会社に転職した話 ~
kimura_m_29
0
180
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
780
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
137
6.7k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
450
Music & Morning Musume
bryan
46
6.2k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
How GitHub (no longer) Works
holman
311
140k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Producing Creativity
orderedlist
PRO
341
39k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
The Pragmatic Product Professional
lauravandoore
32
6.3k
Done Done
chrislema
181
16k
Practical Orchestrator
shlominoach
186
10k
Transcript
#kaigionrails GraphQL Ruby をちょっとだけ速くした GraphQL Ruby を ちょっとだけ速くした @mtsmfm Fumiaki
Matsushima Kaigi on Rails new #kaigionrails
#kaigionrails GraphQL Ruby をちょっとだけ速くした ➔ Web Dev at Quipper ➔
Dead by Daylight 仲間募集 ➔ 西日暮里.rb 主催 ➔ GraphQL Tokyo 主催 @mtsmfm.inspect
#kaigionrails GraphQL Ruby をちょっとだけ速くした https://nishinipporirb.doorkeeper.jp/events/108780
#kaigionrails GraphQL Ruby をちょっとだけ速くした https://www.meetup.com/ja-JP/GraphQL-Tokyo/
#kaigionrails GraphQL Ruby をちょっとだけ速くした 5 GraphQL とは - POST /graphql
{“query”: “{ articles { title }”} したら {“data”: {“articles”: [{“title”: “Hi”}]}} を返すやつ
#kaigionrails GraphQL Ruby をちょっとだけ速くした 6 社内でいくつか GraphQL を導入 - あれ
- これ - それ
#kaigionrails GraphQL Ruby をちょっとだけ速くした 7 ある日鳴る SLO アラート - そのサービスは
90 % 300 ms - 社内サービスなので顧客に約束しているわけではない が放置は NG - 遅い GraphQL クエリがあった
#kaigionrails GraphQL Ruby をちょっとだけ速くした - これでも 200ms 弱くらい 遅いクエリ 8
※リソース名などは実際と異なります
#kaigionrails GraphQL Ruby をちょっとだけ速くした - これすら 70ms 弱 遅いクエリ 9
#kaigionrails GraphQL Ruby をちょっとだけ速くした10 遅いクエリ - DB?
#kaigionrails GraphQL Ruby をちょっとだけ速くした - DB? ❌ - -> 起動時に
YAML を読んで、そこから返している 11 遅いクエリ
#kaigionrails GraphQL Ruby をちょっとだけ速くした12 遅いクエリ - 件数?
#kaigionrails GraphQL Ruby をちょっとだけ速くした - 件数? - -> articles が
20、relatedArticles が 50 ずつくらい - 20 * 50 = 1000 - 多いしクエリの改善の余地がありそう - 実際はクエリをなんとかした - 好奇心: 多くはあるが数百ms もいくか? 13 遅いクエリ
#kaigionrails GraphQL Ruby をちょっとだけ速くした プロファイリング 14 - GraphQL Ruby が怪しい気がする
- とりあえず ruby-prof
#kaigionrails GraphQL Ruby をちょっとだけ速くした15 https://ruby-prof.github.io/
#kaigionrails GraphQL Ruby をちょっとだけ速くした16 ようするにこう
#kaigionrails GraphQL Ruby をちょっとだけ速くした17 CallStackPrinter
#kaigionrails GraphQL Ruby をちょっとだけ速くした18 %self total self wait child calls
name location 5.96 0.659 0.044 0.000 0.615 19241 *<Module::GraphQL::Execution::Execute::ExecutionFunctions>#resolve_value /usr/local/bundle/gems/graphql-1.11.1/lib/graphql/execution/execute.rb:220 5.46 0.156 0.041 0.000 0.115 44528 Concurrent::Collection::MriMapBackend#compute_if_absent bench.rb:14 4.97 0.252 0.037 0.000 0.215 24284 *GraphQL::Schema::LazyHandlingMethods#after_lazy /usr/local/bundle/gems/graphql-1.11.1/lib/graphql/schema.rb:104 3.96 0.079 0.029 0.000 0.049 44532 Thread::Mutex#synchronize 3.95 0.036 0.029 0.000 0.007 44528 Concurrent::Collection::NonConcurrentMapBackend#_get /usr/local/bundle/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb:19 3.61 0.727 0.027 0.000 0.700 6456 *Hash#each FlatPrinter
#kaigionrails GraphQL Ruby をちょっとだけ速くした19 %self total self wait child calls
name location 5.96 0.659 0.044 0.000 0.615 19241 *<Module::GraphQL::Execution::Execute::ExecutionFunctions>#resolve_value /usr/local/bundle/gems/graphql-1.11.1/lib/graphql/execution/execute.rb:220 5.46 0.156 0.041 0.000 0.115 44528 Concurrent::Collection::MriMapBackend#compute_if_absent bench.rb:14 4.97 0.252 0.037 0.000 0.215 24284 *GraphQL::Schema::LazyHandlingMethods#after_lazy /usr/local/bundle/gems/graphql-1.11.1/lib/graphql/schema.rb:104 3.96 0.079 0.029 0.000 0.049 44532 Thread::Mutex#synchronize 3.95 0.036 0.029 0.000 0.007 44528 Concurrent::Collection::NonConcurrentMapBackend#_get /usr/local/bundle/gems/concurrent-ruby-1.1.6/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb:19 3.61 0.727 0.027 0.000 0.700 6456 *Hash#each FlatPrinter
#kaigionrails GraphQL Ruby をちょっとだけ速くした20 Concurrent::Collection:: MriMapBackend#compute_if_absent - map.compute_if_absent(key) { calc(key)
} - ようは hash[:a] ||= ‘a’ みたいな
#kaigionrails GraphQL Ruby をちょっとだけ速くした21 Concurrent::Collection:: MriMapBackend#compute_if_absent - GraphQL Ruby 内では遅延評価するべきかど
うかの判定に使っている (?) - graphql-batch など resolver が Promise なとき用? - 毎度 nil 返ってる
#kaigionrails GraphQL Ruby をちょっとだけ速くした22 Concurrent::Collection:: MriMapBackend#compute_if_absent https://github.com/ruby-concurrency/concurrent-ruby/blob/f749b81cb6c6291640c0004b57e60dbc2b59 a72b/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb#L21-L27
#kaigionrails GraphQL Ruby をちょっとだけ速くした Key があっても格納された値が Falsy なときに毎回 lock とってた
23 https://github.com/ruby-concurrency/concurrent-ruby/blob/f749b81cb6c629164 0c0004b57e60dbc2b59a72b/lib/concurrent-ruby/concurrent/collection/map/mri_ map_backend.rb#L22
#kaigionrails GraphQL Ruby をちょっとだけ速くした なおした 24 https://github.com/ruby-concurrency/concurrent-ruby/pull/879
#kaigionrails GraphQL Ruby をちょっとだけ速くした GraphQL Ruby Concurrent Ruby を ちょっとだけ速くした
@mtsmfm Fumiaki Matsushima Kaigi on Rails new #kaigionrails
#kaigionrails GraphQL Ruby をちょっとだけ速くした26 Warming up -------------------------------------- without patch 1.000
i/100ms with patch 1.000 i/100ms Calculating ------------------------------------- without patch 6.782 (± 0.0%) i/s - 34.000 in 5.030646s with patch 8.633 (±11.6%) i/s - 44.000 in 5.140707s Comparison: with patch: 8.6 i/s without patch: 6.8 i/s - 1.27x (± 0.00) slower 例のクエリが 1.27 倍速くなった
#kaigionrails GraphQL Ruby をちょっとだけ速くした27 ご清聴ありがとうございました - 配列を返す API で、子要素も配列になっていると要素数は M
* N になる (自明) - GraphQL Ruby は 20 * 50 要素 4 フィールドでも 66 ms くら い処理にかかる - Concurrent Ruby の master を使うと 54 ms くらいになる - Concurrent::Map#compute_if_absent で nil 返すのを3倍弱速くしたため - 他にも改善の余地はありそう - 簡易ベンチマークスクリプトを書いた - https://github.com/mtsmfm/graphql-ruby-benchmark-example