zshの起動時に `fpath`配列値の変更が与える影響を減らすにはどうすればよいですか?

zshの起動時に `fpath`配列値の変更が与える影響を減らすにはどうすればよいですか?

私はzshバージョン5.1.1tmuxバージョンを使用していますが、最近新しいシェルを起動する(新しいウィンドウまたはウィンドウを介して)以前よりもはるかに時間がかかることを確認2.3しました。tmux

プロンプトが表示される前に約5文字を入力してください。この時間を減らしたかったので、開始時間を増やす行が見つかるまで、ファイル内returnのさまざまな場所にステートメントを作成しました。zshrcそうだ:

fpath=(~/.zsh/completion $fpath)

次の最小値で問題を再現できますzshrc

fpath=(~/.zsh/completion $fpath)
autoload -Uz compinit
compinit

~/.zsh/completion最初の行は配列の前にパスを追加しますfpath。このディレクトリにカスタム補完関数コードを含むファイルを作成したいので、これを行います。

シェルの起動にかかる時間を知るために、次のコマンドを見つけました。

for i in $(seq 1 10); do /usr/bin/time zsh -i -c exit; done

10個のシェルを連続して開始して終了し、毎回かかる時間を測定します。以前の最小値として報告された内容は次のとおりですzshrc

0.36user 0.04system 0:00.42elapsed 96%CPU (0avgtext+0avgdata 6056maxresident)k
0inputs+160outputs (0major+9087minor)pagefaults 0swaps
0.30user 0.04system 0:00.36elapsed 96%CPU (0avgtext+0avgdata 5900maxresident)k
0inputs+160outputs (0major+8949minor)pagefaults 0swaps
0.30user 0.05system 0:00.37elapsed 96%CPU (0avgtext+0avgdata 6080maxresident)k
0inputs+160outputs (0major+8992minor)pagefaults 0swaps
0.31user 0.04system 0:00.37elapsed 95%CPU (0avgtext+0avgdata 5936maxresident)k
0inputs+160outputs (0major+8956minor)pagefaults 0swaps
0.30user 0.04system 0:00.36elapsed 96%CPU (0avgtext+0avgdata 6052maxresident)k
0inputs+160outputs (0major+9089minor)pagefaults 0swaps
0.32user 0.04system 0:00.38elapsed 96%CPU (0avgtext+0avgdata 5944maxresident)k
0inputs+160outputs (0major+8948minor)pagefaults 0swaps
0.32user 0.04system 0:00.37elapsed 95%CPU (0avgtext+0avgdata 6004maxresident)k
0inputs+160outputs (0major+8991minor)pagefaults 0swaps
0.32user 0.02system 0:00.36elapsed 96%CPU (0avgtext+0avgdata 6056maxresident)k
0inputs+160outputs (0major+9109minor)pagefaults 0swaps
0.30user 0.05system 0:00.36elapsed 96%CPU (0avgtext+0avgdata 6072maxresident)k
0inputs+160outputs (0major+9003minor)pagefaults 0swaps
0.31user 0.04system 0:00.36elapsed 96%CPU (0avgtext+0avgdata 6040maxresident)k
0inputs+160outputs (0major+9055minor)pagefaults 0swaps

私はこの内容を正しく読んでいるかどうかはわかりませんが、シェルの起動0.32に平均1秒かかることを示しているようです。

zshrcその行をコメントアウトした後、同じコマンドが同じ最小値で生成される内容は次のとおりですfpath=(...)

0.08user 0.02system 0:00.10elapsed 97%CPU (0avgtext+0avgdata 5608maxresident)k
0inputs+0outputs (0major+1721minor)pagefaults 0swaps
0.06user 0.00system 0:00.07elapsed 97%CPU (0avgtext+0avgdata 5660maxresident)k
0inputs+0outputs (0major+1723minor)pagefaults 0swaps
0.05user 0.00system 0:00.06elapsed 92%CPU (0avgtext+0avgdata 5680maxresident)k
0inputs+0outputs (0major+1720minor)pagefaults 0swaps
0.05user 0.00system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5724maxresident)k
0inputs+0outputs (0major+1734minor)pagefaults 0swaps
0.04user 0.02system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5748maxresident)k
0inputs+0outputs (0major+1730minor)pagefaults 0swaps
0.05user 0.00system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5692maxresident)k
0inputs+0outputs (0major+1724minor)pagefaults 0swaps
0.04user 0.01system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5636maxresident)k
0inputs+0outputs (0major+1728minor)pagefaults 0swaps
0.04user 0.01system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5628maxresident)k
0inputs+0outputs (0major+1727minor)pagefaults 0swaps
0.04user 0.01system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5684maxresident)k
0inputs+0outputs (0major+1722minor)pagefaults 0swaps
0.05user 0.00system 0:00.06elapsed 95%CPU (0avgtext+0avgdata 5728maxresident)k
0inputs+0outputs (0major+1731minor)pagefaults 0swaps

今、平均して0.052位だけ必要なようです。

デフォルトでは、値は次のとおりですFPATH

/usr/local/share/zsh/site-functions:/usr/share/zsh/vendor-functions:/usr/share/zsh/vendor-completions:/usr/share/zsh/functions/Calendar:/usr/share/zsh/functions/Chpwd:/usr/share/zsh/functions/Completion:/usr/share/zsh/functions/Completion/AIX:/usr/share/zsh/functions/Completion/BSD:/usr/share/zsh/functions/Completion/Base:/usr/share/zsh/functions/Completion/Cygwin:/usr/share/zsh/functions/Completion/Darwin:/usr/share/zsh/functions/Completion/Debian:/usr/share/zsh/functions/Completion/Linux:/usr/share/zsh/functions/Completion/Mandriva:/usr/share/zsh/functions/Completion/Redhat:/usr/share/zsh/functions/Completion/Solaris:/usr/share/zsh/functions/Completion/Unix:/usr/share/zsh/functions/Completion/X:/usr/share/zsh/functions/Completion/Zsh:/usr/share/zsh/functions/Completion/openSUSE:/usr/share/zsh/functions/Exceptions:/usr/share/zsh/functions/MIME:/usr/share/zsh/functions/Misc:/usr/share/zsh/functions/Newuser:/usr/share/zsh/functions/Prompts:/usr/share/zsh/functions/TCP:/usr/share/zsh/functions/VCS_Info:/usr/share/zsh/functions/VCS_Info/Backends:/usr/share/zsh/functions/Zftp:/usr/share/zsh/functions/Zle

変数の始めに私はパスを見つけました/usr/local/share/zsh/site-functions
これは空のディレクトリだったので、それを削除し、ターゲットが私の完了ディレクトリであるシンボリックリンクに置き換えました。

cd /usr/local/share/zsh; sudo rm site-functions; sudo ln -s ~/.zsh/completion site-functions

このシンボリックリンクを使用すると、値を変更する必要はありませんfpath。完了はまだ機能し、シェルの開始時間は40.32秒から約0.08秒に分けられました。その違いは私には明らかです。しかし、システム全体のディレクトリを使用するのは正しくないと感じます。

同じ結果を得るもう一つの良い方法はありますか?


編集する:

ありがとう@thrig、私は私の~/.zsh/ディレクトリが実際にDropboxディレクトリへのシンボリックリンクであることに気づきました。

ls -l .zsh
lrwxrwxrwx 1 user user 16 jan. 18 18:54 .zsh -> Dropbox/conf/zsh

私は設定をバックアップするためにこれを行っていますが、gitの使い方がわからないからです。

補完機能を Dropbox 外部ディレクトリに移動すると、zsh開始時間が大幅に向上します。


編集2:

わかりませんが、zshDropboxディレクトリの外部に完成機能を追加しても、再び遅くなり始めているようです。

役に立つ場合は、次のコマンドの出力をPastebinなどのサイトにアップロードしました。

strace -e trace=desc -o log -r zsh

によると、man straceこの-e trace=descオプションはすべてのファイル記述子関連のシステムコールを追跡する必要があります。この-rオプションは、入力された各システムコールの相対タイムスタンプを印刷する必要があります。

ログリンクは次のとおりです。fpath変更なし
これはログへの2番目のリンクですfpath変更されました

ログファイルを記述することはできませんが、サイズに大きな違いがあります。 1つ目は4000システムコールのみを含むようですが、2つ目は67000


編集3:

また、次のコマンドの出力も記録しました。

PS4='+[%D{%H:%M:%S.%.}]%N:%i> ' zsh -x

...scriptユーティリティを含む。

ログファイルへのリンクは次のとおりです。fpath変更なし
以下はログファイルへのリンクです。fpath変更されました

今回は、最初のログファイルにはおおよその行だけが600含まれ、2番目のログファイルにはおおよその行だけが含まれてい100000ます。

変更されたログファイルでfpath最も一般的に呼び出される関数は、compdef(およそ69000時間)、compinit(おおよそ16000時間)、およびcompdump(おおよそ14000時間)です。

コメントで助けてくれてありがとう。

ベストアンサー1

私のzshバージョンに問題がある可能性があると思い、zshパッケージを消去してソースからコンパイルしました。

% sudo aptitude install git-core gcc make autoconf yodl libncursesw5-dev texinfo

% git clone git://zsh.git.sf.net/gitroot/zsh/zsh
% cd zsh
% git checkout zsh-5.3.1

% ./Util/preconfig

% ./configure --build=x86_64-linux-gnu \
--prefix=/usr \
--includedir=/usr/include \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--sysconfdir=/etc \
--localstatedir=/var \
--libdir=/usr/lib/x86_64-linux-gnu \
--libexecdir=/usr/lib/x86_64-linux-gnu \
--bindir=/bin \
LDFLAGS="-Wl,--as-needed -g" \
--enable-maildir-support \
--enable-etcdir=/etc/zsh \
--enable-function-subdirs \
--enable-site-fndir=/usr/local/share/zsh/site-functions \
--enable-fndir=/usr/share/zsh/functions \
--with-tcsetpgrp \
--with-term-lib="ncursesw tinfo" \
--enable-cap \
--enable-pcre \
--enable-readnullcmd=pager \
--enable-custom-patchlevel=Debian \
--enable-additional-fpath=/usr/share/zsh/vendor-functions,/usr/share/zsh/vendor-completions \
--disable-ansi2knr

INSTALLGoogleで見つけたドキュメントとポイントを読んで、依存関係と設定オプションを見つけました。

https://gist.github.com/nicoulaj/715855

...そして、Ubuntu開発者が最新のパッケージをコンパイルする方法を見てみましょうzsh

https://launchpadlibrarian.net/280509421/buildlog_ubuntu-yakkety-amd64.zsh_5.2-5ubuntu1_BUILDING.txt.gz

2回書き込んだかzshで認識できないオプションがあって削除しました。 Ubuntu開発者が提供した値がLDFLAGS私のコンピュータでは動作しないようで、Githubのgistから1つをコピーしました。私が維持したオプションは次のとおりです./configure --help

--build=BUILD           configure for building on BUILD [guessed]

--prefix=PREFIX         install architecture-independent files in PREFIX
                        [/usr/local]

--includedir=DIR        C header files [PREFIX/include]

--mandir=DIR            man documentation [DATAROOTDIR/man]

--infodir=DIR           info documentation [DATAROOTDIR/info]

--sysconfdir=DIR        read-only single-machine data [PREFIX/etc]

--localstatedir=DIR     modifiable single-machine data [PREFIX/var]

--libdir=DIR            object code libraries [EPREFIX/lib]

--libexecdir=DIR        program executables [EPREFIX/libexec]

--bindir=DIR            user executables [EPREFIX/bin]

 LDFLAGS                linker flags, e.g. -L<lib dir> if you have libraries in a
                            nonstandard directory <lib dir>

--enable-maildir-support
                        enable maildir support in MAIL and MAILPATH

--enable-etcdir=DIR     the default directory for global zsh scripts

--enable-function-subdirs
                        install functions in subdirectories

--enable-site-fndir=DIR same for site functions (not version specific)

--enable-fndir=DIR      the directory in which to install functions

--with-tcsetpgrp        assumes that tcsetpgrp() exists and works correctly

 --with-term-lib=LIBS   search space-separated LIBS for terminal handling

 --enable-cap           enable the search for POSIX capabilities (may
                        require additional headers to be added by hand)

--enable-pcre           enable the search for the pcre library (may create
                        run-time library dependencies)

--enable-readnullcmd=PAGER
                        pager used when READNULLCMD is not set

--enable-custom-patchlevel
                        set a custom ZSH_PATCHLEVEL value

--enable-additional-fpath=DIR
                        add directories to default function path

--enable-ansi2knr       translate source to K&R C before compiling

コンパイルは成功しましたが、make checkコマンドで実行された48のテストのうち2つが失敗しました。

% make
% make check
**************************************
46 successful test scripts, 2 failures, 0 skipped
**************************************
Makefile:187: recipe for target 'check' failed
make[1]: *** [check] Error 1
make[1]: Leaving directory '/home/user/GitRepos/zsh/Test'
Makefile:263: recipe for target 'check' failed
make: *** [check] Error 2

私はそれらを削除することはできません。

make install最後に、以前にバイナリをインストールするためにこれを使用するのではなく、後でシェルを変更する必要がある場合は削除することができます(を使用して)checkinstall.debdpkg -r zsh

% sudo checkinstall

インストール中に簡単な説明(私が使用したもの)を提供する必要があり、shell with lots of featuresさらに重要なことはバージョンを提供する必要があることです。 Debianポリシーと互換性のあるバージョンがないと checkinstallビルドされません.deb。 Debianがどの命名スキームを使用しているかを確認するために、Debianの出力を見てみましたが、apt-cache policy zshそれが選択されました5.3.1-1ubuntu2

% echo /bin/zsh >> /etc/shells
% chsh  →  /bin/zsh

/bin/zshこれら2行は、Ubuntuがそれを有効なログインシェルとして認識し、それをデフォルトシェルにするために必要です。

これで、シェルのバージョンは5.3.1次のようになります5.1.1

% zsh --version
    zsh 5.3.1 (x86_64-pc-linux-gnu)

シェルがすばやく起動します(約0.04s)。

% repeat 10 =time zsh -i -c exit

    0.06user 0.03system 0:00.12elapsed 80%CPU (0avgtext+0avgdata 5592maxresident)k
    0inputs+0outputs (0major+5668minor)pagefaults 0swaps
    0.06user 0.01system 0:00.09elapsed 77%CPU (0avgtext+0avgdata 5480maxresident)k
    0inputs+0outputs (0major+5634minor)pagefaults 0swaps
    0.04user 0.01system 0:00.07elapsed 82%CPU (0avgtext+0avgdata 5736maxresident)k
    0inputs+0outputs (0major+5641minor)pagefaults 0swaps
    0.04user 0.01system 0:00.07elapsed 77%CPU (0avgtext+0avgdata 5652maxresident)k
    0inputs+0outputs (0major+5645minor)pagefaults 0swaps
    0.03user 0.03system 0:00.07elapsed 82%CPU (0avgtext+0avgdata 5736maxresident)k
    0inputs+0outputs (0major+5634minor)pagefaults 0swaps
    0.04user 0.01system 0:00.07elapsed 78%CPU (0avgtext+0avgdata 5548maxresident)k
    0inputs+0outputs (0major+5624minor)pagefaults 0swaps
    0.04user 0.02system 0:00.07elapsed 78%CPU (0avgtext+0avgdata 5612maxresident)k
    0inputs+0outputs (0major+5655minor)pagefaults 0swaps
    0.04user 0.01system 0:00.07elapsed 77%CPU (0avgtext+0avgdata 5780maxresident)k
    0inputs+0outputs (0major+5624minor)pagefaults 0swaps
    0.03user 0.02system 0:00.07elapsed 78%CPU (0avgtext+0avgdata 5584maxresident)k
    0inputs+0outputs (0major+5641minor)pagefaults 0swaps
    0.03user 0.02system 0:00.07elapsed 78%CPU (0avgtext+0avgdata 5668maxresident)k

最初のコンパイル時に最新のリリースブランチに切り替えることを忘れていたため、この開発バージョンのmaster起動時間はUbuntuリポジトリのバージョンよりはるかに悪かったです。周囲にシェルを起動します。しかし、もう一度申し上げますが、にディレクトリを追加して後者にファイルを作成する場合にのみ可能です(単純なファイルであれば十分です)。
zsh0.42sfpathzshrctouch file

したがって、問題がコンパイルオプションで発生するのか、それともリリースバージョンで発生するのか疑問に思います。私がコンパイルしたディストリビューションのバージョンをすばやく維持したいです。

ありがとう@thrightそしておめでとうございますコメントで助けてください。

おすすめ記事