Upgrade to Pro — share decks privately, control downloads, hide ads and more …

その処理、本当に遅いですか? 〜無駄を削る達人になろう〜

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

その処理、本当に遅いですか? 〜無駄を削る達人になろう〜

その処理、本当に遅いですか? 〜無駄を削る達人になろう〜

Avatar for Tech Leverages

Tech Leverages

June 30, 2023
Tweet

More Decks by Tech Leverages

Other Decks in Technology

Transcript

  1. 自己紹介 桐生直輝 (23歳) • 入社:2023年3月 • 出身:岡山県津山市 • 所属:HRテック事業部 ◦

    バックエンド〜インフラ担当 • 趣味:コンピュータいじり、自宅サーバー構築 • 目標は技術力でとことん尖ることです
  2. 「無駄」を感じ取るには 何をするのにどれくらいの時間がかかるか、感覚を掴む • 例えば、現代のCPUがどのくらい高速か知っているでしょうか? 例:CPU vs ストレージ vs ネットワークアクセス 1秒あたりの処理能力比較

    (目安) 3,000,000,000 IPS 1,000,000 IOPS 1,000 RPS 1回のネットワーク通信の完了を待つ間に、 SSDは1000回の読み書きを実行でき、 CPUは300万回の計算を実行できる。 ※並列度=1
  3. 「無駄」を感じ取るには 処理時間を概算してみる • 例:100ユーザーで、各ユーザー1000件程度のデータを集計する(合計・平均など) ◦ トータルの処理件数は 100 * 1000 =

    10万件程度 ◦ 単純な集計なら1件あたり数十ステップで処理可能 →実時間では数ミリ秒程度 ◦ DBからのデータの取得も 10万件程度なら最大で数秒程度しかかからないはず • ここで概算した時間(数秒)を大きく上回る場合、無駄が存在することになる
  4. 計測の手法 経過時間を計測し、ログ出力 • ポイントごとの時刻を記録し、その差分から処理時間を算出する function run() { const startTime =

    new Date(); // new Date() は現在の時刻を取得する const data = getData(); const afterGetDataTime = new Date(); const transformed = transformData(data); const afterTransformTime = new Date(); saveData(transformed); const afterSaveDataTime = new Date(); console.log(‘getData():’, afterGetDataTime - startTime, ‘ms’); console.log(‘transformData():’, afterTransformTime - afterGetDataTime, ‘ms’); console.log(‘saveData():’, afterSaveDataTime - afterTransformTime, ‘ms’); }
  5. 高速化の実施 例:月次の勤怠締め操作 (給与計算ソフト) • 1ヶ月分の勤怠データを締めて給与額を算出する処理 • 300人分のデータで7分以上かかる • 処理量が多いためであると諦められていたが、計算内容と処理時間が乖離していると感じ 高速化に着手

    ◦ 300人 * 30日 = 9000個の勤怠データの集計 + 過去の有給使用データ (300人 * 数十件 = 数 千〜1万件) の集計 ◦ データの取得等含めて考えても何十秒もかかるのですらおかしい
  6. 高速化の実施 1ユーザーごとに多数のクエリを発行していた • ループ内でクエリを発行していた &同じデータを何回も取ってきていた ◦ 何万回ものクエリ発行 ◦ ネットワーク通信待ち +

    クエリ実行のオーバーヘッドで結構時間を取られる • 全ユーザーのデータを予め一括で取得するようにして解決 ◦ 1件SELECTを10000回やるより10000件SELECTを1回の方が圧倒的に速い
  7. 高速化の実施 例2:TypeORM マイグレーションの高速化 • マイグレーション = DBスキーマ変更クエリの実行 • マイグレーションコマンドが立ち上がるまでに 10分弱かかっていた

    • どう考えても時間のかかり方が異常で、無駄がありそう ◦ ただマイグレーションのクエリ実行を準備するのに 10分もかからないはずなので
  8. 高速化の実施 TypeScriptのコンパイルがそんなに重いはずがない • 確かにtsファイル数は多い(2000ファイル弱) • しかし、プロジェクトのビルド(npm run build)には10秒くらいしかかからない • 仮説:

    ts-nodeが1ファイルずつビルドしているのでオーバーヘッドが大きく、重い? ◦ 同じファイルを何度もコンパイルしている可能性?