Skip to main content

โฑ๏ธ Startup Profiling

Profile functions with zprofโ€‹

The zsh/zprof module records timing information for shell functions. Load it near the top of .zshrc, then print the report after the code being measured:

~/.zshrc
zmodload zsh/zprof

# Load the functions or configuration to measure here.

zprof

Profiling continues while the module is loaded. Start a fresh Zsh process for each comparison so one run does not include earlier function calls. See the zsh/zprof module reference for the report columns and sorting options.

Trace startup linesโ€‹

For line-by-line timing, guard Zsh's execution trace behind a variable. Place this near the top of .zshrc:

~/.zshrc
typeset -g PROFILE_STARTUP=${PROFILE_STARTUP:-false}

if [[ $PROFILE_STARTUP == true ]]; then
zmodload zsh/zprof
PS4=$'%D{%M%S%.} %N:%i> '
exec 3>&2 2>"$HOME/startlog.$$"
setopt xtrace prompt_subst
fi

Place the matching cleanup near the bottom:

~/.zshrc
if [[ $PROFILE_STARTUP == true ]]; then
unsetopt xtrace
exec 2>&3 3>&-
zprof >"$HOME/zshprofile.$(date +%s)"
fi

Run a new interactive Zsh with PROFILE_STARTUP=true zsh -i. The trace is written to $HOME/startlog.<pid>, and the function report is written to $HOME/zshprofile.<timestamp>.

Add lightweight checkpointsโ€‹

For coarse comparisons, use Zsh's floating-point SECONDS parameter and an array:

~/.zshrc
typeset -ga ZLOGS
typeset -F4 SECONDS=0

zmsg() {
ZLOGS+=("$1: $((SECONDS * 1000)) ms")
}

# Run a section to measure.
zmsg 'Loaded functions'

# Run another section.
zmsg 'Loaded something else'

zmsg 'Done'

Print the collected checkpoints after startup:

print -rl -- $ZLOGS