🏃
キャッシュを利用してCircleCIのRuboCopを高速化する (35秒 -> 4秒)
はじめに
ローカル環境などでRuboCopを実行する際にはよしなにキャッシュが利用され、高速化が図られています。
一方で、CircleCI上ではそうはいきません。RuboCopのキャッシュディレクトリを設定し、設定したディレクトリをCircleCIの依存関係のキャッシュ[1]を用いて次回以降のジョブに使い回す必要があります。
そこで、以下をまとめました。
- キャッシュの利用によってどの程度の改善が見込めるのか
- キャッシュの設定方法
キャッシュの有無による実行時間の比較
先にまとめを貼ります。
キャッシュの有無 | RuboCop (秒) | キャッシュのリストア (秒) | 合計 (秒) |
---|---|---|---|
無し | 35 | 0 | 35 |
有り | 4 | 1 | 5 |
キャッシュを利用しない場合
RuboCopの実行時間は35秒、全体の実行時間は54秒でした。
キャッシュを利用した場合
RuboCopの実行時間は4秒、全体の実行時間は22秒でした。
キャッシュのリストアに要する時間 (1秒) を加味しても、実行時間が1/7になっています。
設定
各種設定を以下にまとめます。
- RuboCopの設定
- CircleCIの設定
RuboCopの設定 (抜粋)
.rubocop.yml
にキャッシュに関する設定[2]を記述します。
以下は関連する部分のみ抜粋したものです。
.rubocop.yml
AllCops:
UseCache: true # デフォルトはtrue
CacheRootDirectory: tmp # デフォルトは$HOME/.cache/
CircleCIの設定
比較のために2通りのジョブを定義したものです。
rubocop-without-using-cache
では、RuboCopのキャッシュを利用しないでrubocopを実行しています。一方で、rubocop-with-using-cache
では次回以降にRuboCopのキャッシュを持ち越すための設定が追加されています。
差分がわかりやすいよう、rubocopの実行とキャッシュ周りの処理以外は setup-rubocop
にまとめています。
.circleci/config.yml
version: 2.1
commands:
setup-rubocop:
steps:
- checkout
- run:
name: Install RuboCop
command: |
gem install rubocop
jobs:
rubocop-without-using-cache:
docker:
- image: cimg/ruby:3.0.6
resource_class: xlarge
steps:
- setup-rubocop
- run:
name: Run RuboCop
command: |
rubocop
rubocop-with-using-cache:
docker:
- image: cimg/ruby:3.0.6
resource_class: xlarge
steps:
- setup-rubocop
- restore_cache:
keys:
- rubocop-cache-{{ .Branch }}-{{ .Revision }}
- rubocop-cache-{{ .Branch }}-
- rubocop-cache-
- run:
name: Run RuboCop
command: |
rubocop
- save_cache:
key: rubocop-cache-{{ .Branch }}-{{ .Revision }}
paths:
- tmp/rubocop_cache
workflows:
ci_cd:
jobs:
- rubocop-without-using-cache
- rubocop-with-using-cache
おわりに
ちょっとしたコード変更でも大きな改善が得られました。
RuboCopに限らず、ローカルと比べてCircleCI上では遅い事象に遭遇した際には、ローカルにキャッシュディレクトリが作られている可能性を疑うと良いかもしれません。
参考
Discussion