zsh 시작 시간에 `fpath` 배열 값 변경이 미치는 영향을 줄이는 방법은 무엇입니까?

zsh 시작 시간에 `fpath` 배열 값 변경이 미치는 영향을 줄이는 방법은 무엇입니까?

저는 zshversion 5.1.1tmuxversion 을 사용하고 있는데 최근에 새 셸을 시작하는 데( 의 새 창이나 창을 통해 ) 이전보다 훨씬 더 많은 시간이 걸리는 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

변수의 시작 부분에서 나는 path 를 발견했습니다 /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변경 없음.
이것은 로그에 대한 두 번째 링크입니다fpath변경되었습니다.

로그 파일을 설명할 수는 없지만 크기에 큰 차이가 있습니다. 첫 번째는 4000시스템 호출만 포함하는 것으로 보이지만 두 번째는 67000.


편집 3:

또한 다음 명령의 출력도 기록했습니다.

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

... script유틸리티 포함.

로그 파일에 대한 링크는 다음과 같습니다.fpath변경 없음.
다음은 로그 파일에 대한 링크입니다.fpath변경되었습니다.

이번에는 첫 번째 로그 파일에는 대략적인 600줄만 포함되어 있고 두 번째 로그 파일에는 대략적인 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

두 번 썼거나 zsh에서 인식하지 못하는 옵션이 있어서 삭제했습니다. Ubuntu 개발자가 제공한 값이 LDFLAGS내 컴퓨터에서는 작동하지 않는 것 같아서 Github의 gist에서 하나를 복사했습니다. 내가 유지한 옵션은 다음과 같습니다 ./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더 중요한 것은 버전을 제공해야 한다는 것입니다. 데비안 정책과 호환되는 버전이 없으면 checkinstall빌드되지 않습니다 .deb. 데비안이 어떤 명명 체계를 사용하고 있는지 확인하기 위해 데비안의 출력을 살펴보았는데 apt-cache policy zsh그것이 선택되었습니다 5.3.1-1ubuntu2.

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

/bin/zsh이 두 줄은 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그리고@stefanchazeras댓글로 도와주세요.

관련 정보