関連記事
TL;DR
zplugを使うのやめた。
zcompile最強
はじめに
男たるもの常に最速を目指さないといけないと思っているvinterです。
嘘です。ちょっと卒論がやばいので現実逃...ではなく息抜きにzshの起動速度のチューンをしていました。
なので正確なデータを取り忘れました。すみません。
以前zshの起動が遅いのでなんとかしたいという記事を書いたのでよければそちらもどうぞ。
初っ端からちょっとアレでしたが、別にzplugをディスているわけではないです。zplugはとても素晴らしいプラグインマネージャーです。
プロファイル取る時分かりにくかったのと、もともとそんなにプラグイン使っていなかったので使うのやめた感じです。
現状
zshの起動速度を見るために以下のコマンドで計測しています。
time ( zsh -i -c exit )
これで大体200msぐらいでした。そのうち、自分で書いた設定ファイルが50ms、zplug関連が150msでした。なのでこれ以上の高速化をするならzplugとプラグインをどうにかしないといけないなとなりました。
原因究明
まずzplugが遅いのか、そもそもプラグインが重いのかを計るために0プラグインでzplugをloadしてみました。
それでも50~100msくらいかかってました。
zprofで見てみるとzplugの__load__
が結構時間かかっていますね。特にcompinitが-iなのでこれが全体の50%ほど時間を占めているようです。
zplug脱却
compinit -i
をcompinit -C
にするとセキュリティチェックをすべて全て飛ばすので数倍早くなります。
ただ残念ながらzplug内でcompinitをしているので、外部からいじれません。
なのでzplugをやめで手動でロードするようにしました。
つまり今はzplugでプラグインインストールやアップデート→ロードは手動
というちょっとひどい構成になっています。
zplugがcompinitのオプションを外部から変更出来るようになったら戻ってくると思います。
そもそも常に-Cというのも流石に不安なので定期的にcompinitをするべきでしょう。こういう感じにすれば、一応定期的にcompinit出来ますがあんまりキレイな書き方ではないですね。
一時の快楽(高速化)のために不便を強いているような...
compinitの速度についていっぺん調べてみたいのですが、何がどう影響しているのか知識がなくて諦めました。
ともあれこれで80msほど短縮。
プラグインの調整
compinit
が一番重い処理でしたが、そもそもプラグイン自体も結構ロードに時間がかかっています。
自分の場合zsh-syntax-highlightingが30ms、enhancdが20msかかっていました。
このうち、enhacdはlogファイルを保存しておくためのmkdirとtouchを毎回していたので、すでに存在したら飛ばすようにしたら10ms縮まりました。
--- a/init.sh
+++ b/init.sh
@@ -43,8 +43,12 @@ __enhancd::init::init()
unset src
# make a log file and a root directory
- mkdir -p "$ENHANCD_DIR"
- touch "$ENHANCD_DIR/enhancd.log"
+ if [ ! -d "$ENHANCD_DIR" ]; then
+ mkdir -p "$ENHANCD_DIR"
+ fi
+ if [ ! -f "$ENHANCD_DIR/enhancd.log" ]; then
+ touch "$ENHANCD_DIR/enhancd.log"
+ fi
あとはsrc
以下のファイルをzcompileしたところ6msぐらいなりました。最初の4倍ですね!
ところでこのenhancdってautoloadじゃ駄目だったんかな?重いよね。
zsh-syntax-highlightingは_zsh_highlight_load_highlighters
という関数が30msほどかかっていました。
これは大量のファイルをsourceしているところなのでhighlighters
ディレクトリ以下のzshファイルを全部zcompileしちゃいます。
for f in $(find . -name "*.zsh"); do zcompile $f; done
なんと3msになりました!10倍です!10倍!
結果
~
❯ type zshtime
zshtime is an alias for for i in $(seq 1 10); do time zsh -i -c exit; done
~
❯ zshtime
zsh -i -c exit 0.05s user 0.05s system 87% cpu 0.122 total
zsh -i -c exit 0.04s user 0.04s system 100% cpu 0.077 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.076 total
zsh -i -c exit 0.04s user 0.04s system 100% cpu 0.076 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.081 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.079 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.077 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.077 total
zsh -i -c exit 0.04s user 0.04s system 101% cpu 0.079 total
zsh -i -c exit 0.04s user 0.04s system 100% cpu 0.077 total
ついに100ms切りました。やったね。
デメリット
今回の高速化で以下の点を気にする必要が出来ました。
- zcompdumpが壊れていないのか。
- zcompdumpのzcompileを行う。
- プラグインを更新したとき、zcompileを手動でする。
結論
zcompile最強。
ロードする時自動でzcompileする用に設定とか出来ないんですかね?
Appendix
基本的にzprofで見ているのですが、もう少し詳しくみたい時があります。そのとき以下のようにすると行ごとにtimestampがとれて便利です。
zmodload zsh/datetime
setopt promptsubst
PS4='+$EPOCHREALTIME %N:%i> '
exec 3>&2 2>/tmp/zsh_profile.$$
setopt xtrace prompt_subst
# 計測したい処理
trap 'unsetopt xtrace' EXIT
exec 2>&3 3>&-
+1481803140.2755711079 _zsh_highlight_load_highlighters:8> setopt localoptions noksharrays
+1481803140.2756168842 _zsh_highlight_load_highlighters:11> [[ -d /Users/vinter/.zplug/repos/zsh-users/zsh-syntax-highlighting/highlighters ]]
+1481803140.2756500244 _zsh_highlight_load_highlighters:17> local highlighter highlighter_dir
+1481803140.2757830620 _zsh_highlight_load_highlighters:18> highlighter_dir=/Users/vinter/.zplug/repos/zsh-users/zsh-syntax-highlighting/highlighters/brackets/
+1481803140.2757980824 _zsh_highlight_load_highlighters:19> highlighter=brackets
+1481803140.2758131027 _zsh_highlight_load_highlighters:20> [[ -f /Users/vinter/.zplug/repos/zsh-users/zsh-syntax-highlighting/highlighters/brackets/brackets-highlighter.zsh ]]
...