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
インターンでハチナイのAPIを高速化しました!
Search
akatsukinewgrad
December 17, 2021
0
950
インターンでハチナイのAPIを高速化しました!
akatsukinewgrad
December 17, 2021
Tweet
Share
More Decks by akatsukinewgrad
See All by akatsukinewgrad
2023/1/25_QAテスター meet up!
akatsukinewgrad
0
110
成果発表資料.pdf
akatsukinewgrad
0
1.9k
広大なフィールドを気持ちよく駆け抜けるための技術.pdf
akatsukinewgrad
0
480
正規表現とReDoS.pdf
akatsukinewgrad
0
470
Unityで大量のオブジェクト_を吹き飛ばしたい.pdf
akatsukinewgrad
0
500
新卒2年目が思う1年目の学び.pdf
akatsukinewgrad
0
450
障害訓練の取り組みについて.pdf
akatsukinewgrad
0
580
7分でわかるアカツキゲームス
akatsukinewgrad
0
490
Bitcoinだけでスマートコントラクト.pdf
akatsukinewgrad
1
760
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
22
1.2k
How GitHub (no longer) Works
holman
311
140k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
BBQ
matthewcrist
85
9.4k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
Visualization
eitanlees
146
15k
Scaling GitHub
holman
458
140k
Transcript
インターンで ハチナイのAPIを高 速化しました!
自己紹介 ▣ 長谷川 貴斗 ▣ 京都大学大学院 情報学研究科 数理工学専攻 M1(23卒) ▣
先月10月にアカツキの就業型インターン(Ruby on Rails, 八月のシンデレラナイン)に1ヶ月参加 ▣ アカツキインターンでの担当業務 □ 管理画面の開発 □ バリデーションの追加 □ 新規機能開発 □ APIの高速化← ▣ 趣味 □ 喫茶店(モス,ドトール,近所)で読書 □ お絵描き 2
目次 ▣ 何を高速化したいのか ▣ どのくらい遅いのか ▣ どうやって高速化したのか □ 既存のコードの問題点 □
解決策 ▣ どのくらい高速化されたのか ▣ まとめ 3
1. 何を 高速化したいのか 4
高速化したいAPI ▣ 八月のシンデレラナイン ▣ チャプター情報一覧取得API □ ステージは解放済み? □ チャプターはボーナス期間? □
クリアスターはいくつ? などチャプターに関する情報諸々を取ってくるAPI 5
APIが返却するデータ ▣ 返却するデータは大きく分けると □ マスターデータだけで計算できるもの ▪ チャプターはボーナス期間中か □ ユーザーデータが計算に必要なもの ▪
チャプターはクリア済か ▣ マスターデータ □ 選手情報,能力値やスカウトの開催時期など ▣ ユーザーデータ □ ミッションのクリア状況や獲得経験値など 6
2. どのくらい 遅かったのか 7
計測結果 3957ms (Views: 2452.5ms | ActiveRecord: 251.4ms) ▣ Viewsも遅いが,ViewsとActiveRecord以外の部分もかなり時 間かかってる
→Controllerに遅い処理がありそう... 8
大量のpreload ▣ Chapterの関連テーブルを 読み込むところの処理が 1300msほどかかっていた. 9
なぜ遅いか ▣ preload □ クエリの使用回数を減らすために関連づけられたレコードを一括で読み込む □ いわゆるN+1問題を解消するのによく使われる ▣ 遅い理由 □
レコード数が多いものでは20000ほどもあり,preloadするとそれぞれに対 してActiveRecordインスタンスが生成.さらにそれぞれのレコードに対して カラム数分だけActiveRecord::AttributeMethods関連オブジェクトのメ ソッドが呼ばれたりして.生成コストが高くなる つまり,レコード数が多い時preloadはそれなりに重たい. 10
3. どうやって 高速化したのか 11
preloadする回数を減らしたい かといって,ただpreloadをやめるだけではN+1が起きてしまう ▣ マスターデータだけで計算できるデータは,アプデなどでマスターデー タが変更されない限り不変. □ 一回計算した後はキャッシュに持たせておけば,preloadしなくて 済む. ▣ キャッシュはマスターデータが変更されるときに削除
12
APIが返却するデータ(再掲) ▣ 返すデータは大きく分けると □ マスターデータだけで計算できるもの ▪ チャプターはボーナス期間中か □ ユーザーデータに紐づくもの ▪
チャプターはクリア済か ▣ マスターデータ □ 選手情報,能力値やスカウトの開催時期など ▣ ユーザーデータ □ ミッションのクリア状況や獲得経験値など 13
他にも色々 ▣ N+1っぽい問題が起こっている箇所の修正 ▣ キャッシュを作る時だけpreloadが必要だが,毎回preloadしてし まっていた箇所を修正 など... 14
4. どのくらい 高速化されたのか 15
結果 3957ms→1871ms!! 50%程高速化できました. 16
5. まとめ 17
まとめ ▣ 「N+1問題」を起こさないのは基本 ▣ 「ActiveRecordインスタンスの生成コスト」はそれなりに高い ▣ 変更される頻度が低いデータはキャッシュに持たせるという解決策 をとった. - Future
Work ▣ 技術の選定(たとえばErlangだとプロセスをまたがる場合でも内蔵 のオンメモリDBが使えたりするらしい...) ▣ joinとかpluckを使ってActiveRecordインスタンスを生成しない みたいな方法もあったのかも 18