Edited at

.zshrcをちょっと書き換えて起動を3倍速くした話

rubyを使っている方々、 rbenv を使っているのではないでしょうか。

k8sを使っている方々、 kubectl は必需品ですよね。 kubesec, helm もよく使うかもしれません。

それらの設定を .zshrc にそのまま書いていませんか?僕は書いていました。

チューニング前の簡易なベンチマークの結果がこちらです。

$ for i in {1..10} ; do time ( zsh -i -c exit ); done

( zsh -i -c exit; ) 0.59s user 0.19s system 115% cpu 0.677 total
( zsh -i -c exit; ) 0.65s user 0.13s system 111% cpu 0.699 total
( zsh -i -c exit; ) 0.60s user 0.19s system 107% cpu 0.735 total
( zsh -i -c exit; ) 0.63s user 0.17s system 101% cpu 0.780 total
( zsh -i -c exit; ) 0.57s user 0.22s system 103% cpu 0.760 total
( zsh -i -c exit; ) 0.63s user 0.15s system 109% cpu 0.713 total
( zsh -i -c exit; ) 0.72s user 0.19s system 96% cpu 0.950 total
( zsh -i -c exit; ) 0.61s user 0.19s system 108% cpu 0.734 total
( zsh -i -c exit; ) 0.69s user 0.21s system 99% cpu 0.899 total
( zsh -i -c exit; ) 0.64s user 0.15s system 101% cpu 0.775 total

だいたい 0.7~0.9秒ほどかかっていますね。

別に何か大きな損失があるわけではないですが、ターミナルを開いてワンテンポ遅れてプロンプトが表示されるのが気になっていました。

そんな .zshrc をチューニングした結果がこちらです。

$ ( zsh -i -c exit; )  0.14s user 0.03s system 72% cpu 0.232 total

( zsh -i -c exit; ) 0.15s user 0.02s system 68% cpu 0.237 total
( zsh -i -c exit; ) 0.13s user 0.03s system 70% cpu 0.232 total
( zsh -i -c exit; ) 0.13s user 0.04s system 72% cpu 0.232 total
( zsh -i -c exit; ) 0.13s user 0.05s system 36% cpu 0.466 total
( zsh -i -c exit; ) 0.15s user 0.07s system 64% cpu 0.338 total
( zsh -i -c exit; ) 0.13s user 0.03s system 71% cpu 0.226 total
( zsh -i -c exit; ) 0.13s user 0.04s system 69% cpu 0.248 total
( zsh -i -c exit; ) 0.13s user 0.04s system 61% cpu 0.279 total
( zsh -i -c exit; ) 0.15s user 0.03s system 70% cpu 0.251 total

0.2~0.3秒ほどになりました。3倍前後の高速化です。

今回は長々と難しいチューニングをすることなくお手軽にzshの起動を速くする方法を紹介します。

と言ってもほぼ受け売りなんですけど。


kubectl, kubesec, helmの補完設定の遅延化

kubectlsource <(kubectl completion zsh) で入力補完の設定ができます。 kubesec, helm も同様です。

zshrcのプロファイリングをしたところ、この3つの実行に多くの時間がかかっていました。

そこで zshの起動が遅かったので早くできないかチャレンジした - hatappi.blog を参考に

if type kubectl > /dev/null 2>&1; then

source <(kubectl completion zsh)
fi

kubectl() {

unfunction "$0"
source <(kubectl completion zsh)
$0 "$@"
}

と書き換えました。

関数化することで最初に kubectl を呼ばれた時に補完設定を行っています。

また、 unfunction を使うことで二回目以降は直接 kubectl を呼んでいます。

同様の書き換えを kubesec, helm でも行いました。


rbenv init の遅延化

同様に rbenv init - の部分も書き換えたいところですが、 rbenv init - では PATH の設定も行っています。そのため、一行書き加えました

before:

export PATH="$HOME/.rbenv/bin:$PATH"

eval "$(rbenv init -)"

after:

export PATH="$HOME/.rbenv/bin:$PATH"

export PATH="/home/tech/.rbenv/shims:${PATH}"
rbenv() {
unfunction "$0"
eval "$(rbenv init -)"
$0 "$@"
}


おわり

以上4箇所の書き換えで3倍ほど高速化しました。

前述の記事をそのまま自分の .zshrc に適用しただけですが、簡単に速くなったのと、手法がとても面白かったので書きました。