【发布时间】:2011-05-20 01:42:32
【问题描述】:
似乎我的 shell 启动时间太长了。有什么方法可以分析它,以便我弄清楚是什么让它这么慢?
【问题讨论】:
似乎我的 shell 启动时间太长了。有什么方法可以分析它,以便我弄清楚是什么让它这么慢?
【问题讨论】:
Zsh 有一个分析模块。在~/.zshrc或~/.zshenv开头添加如下:
# Uncomment to use the profiling module
# zmodload zsh/zprof
取消注释,启动一个新的交互式shell,然后运行命令zprof。您将获得一份详细的项目列表,您可以查看这些项目以更好地了解您的性能瓶颈在哪里:
num calls time self name
-----------------------------------------------------------------------------------
1) 1 7.29 7.29 19.60% 7.29 7.29 19.60% _p9k_init_ssh
2) 2 6.72 3.36 18.06% 6.63 3.31 17.81% gitstatus_start_impl
3) 1 4.00 4.00 10.75% 4.00 4.00 10.75% _p9k_must_init
4) 3 19.28 6.43 51.80% 3.82 1.27 10.28% (anon)
5) 1 1.63 1.63 4.37% 1.63 1.63 4.37% _p9k_restore_state_impl
6) 1 16.92 16.92 45.46% 1.61 1.61 4.32% _p9k_precmd_impl
7) 1 7.13 7.13 19.16% 0.87 0.87 2.33% _p9k_set_prompt
8) 22 6.26 0.28 16.83% 0.84 0.04 2.27% _p9k_build_segment
9) 17 0.82 0.05 2.19% 0.82 0.05 2.19% _p9k_param
10) 6 2.24 0.37 6.02% 0.74 0.12 1.98% _p9k_left_prompt_segment
11) 5 0.59 0.12 1.60% 0.59 0.12 1.60% add-zsh-hook
12) 1 3.05 3.05 8.20% 0.58 0.58 1.56% prompt_dir
这里有一个来自speeding up zsh 的单行字,如果开始时间不规律,您会很感激:
for i in $(seq 1 10); do /usr/bin/time zsh -i -c exit; done
运行该作业,您应该会看到如下输出:
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
0.05 real 0.02 user 0.02 sys
利润。
【讨论】:
您可以在~/.zshrc 中的第一个可疑点(或开头)开始计时:
integer t0=$(date '+%s') # move this around
... maybe something suspect ...
# End of zshrc
function {
local -i t1 startup
t1=$(date '+%s')
startup=$(( t1 - t0 ))
[[ $startup -gt 1 ]] && print "Hmm, poor shell startup time: $startup"
}
unset t0
如果我看到启动速度太慢,这会提醒我,并将其作为永久包装器保留。
对于更复杂的测量,有一个名为 zprof 的 zsh 模块。就像将~/.zshrc 的内容临时包装在zmodload zsh/zprof 和zprof 中一样简单。这将转储一些很容易解释的详细分析表。
zshmodules(1) 手册页中的更多信息。
当我发现特别慢的东西(rbenv init、vcs_info check-for-changes、antigen、nvm、zsh-mime-setup、解释器版本检查等)时,我添加SLOW cmets 作为提醒,并尝试找到解决方法。缓慢的启动会导致很多痛苦,所以我倾向于避免使用我不了解其内部工作原理的 zsh 包/框架字。 compinit 是我愿意忍受的最慢的东西,大约是总启动时间的一半。
【讨论】:
尝试在文件开头添加:
# set the trace prompt to include seconds, nanoseconds, script name and line number
# This is GNU date syntax; by default Macs ship with the BSD date program, which isn't compatible
PS4='+$(date "+%s:%N") %N:%i> '
# save file stderr to file descriptor 3 and redirect stderr (including trace
# output) to a file with the script's PID as an extension
exec 3>&2 2>/tmp/startlog.$$
# set options to turn on tracing and expansion of commands contained in the prompt
setopt xtrace prompt_subst
最后是这个:
# turn off tracing
unsetopt xtrace
# restore stderr to the value saved in FD 3
exec 2>&3 3>&-
你应该得到一个详细的日志,显示每行执行的 epoch_second.nanosecond 时间。请注意,GNU date(和操作系统支持)需要具有纳秒级输出。
编辑:
添加了 cmets
编辑 2:
如果你有 zsh 4.3.12 或更高版本,你应该可以像这样设置PS4 而不是使用date 命令:
zmodload zsh/datetime
setopt promptsubst
PS4='+$EPOCHREALTIME %N:%i> '
它应该可以在 Linux 和 OS X 上运行,从而为您提供纳秒级精度。
【讨论】:
setopt prompt_subst - 否则$(date ..) 部分不会被替换。
%D{%s%.} 代替$EPOCHREALTIME