How to benchmark bashrc / zshrc and prompt rendering time?

As im currently experimenting with new stuff in my prompt i need a way to tell what the performance impact is.

How can i monitor how long it takes to render my prompt and the time it takes to source the .*rc?


With these command you should be able to benchmark the startup times, including sourcing of rc files (+ one print invocation, which shouldn't add to much overhead):

time zsh -i -c "print -n"
time bash -i -c "echo -n"

With more than 1000 lines in my .zshrc this takes 0.3 sec on my cygwin installation. And no, it's really no high-end-machine (iCore2Duo P8700).

Regarding the prompt rendering time:

  • in bash it's possible to time builtin commands. However, I don't know a possibility to render $PS1 as a prompt.

  • in zsh it's the other way round, with print -P $PS1 $RPS1 you can render you prompt with a print command. (man zshbuiltins: "[print] -P Perform prompt expansion"). But it seems time doesn't work with builtin commands. That's why I hacked together this one:

    cumul=0; for i ({0..99}) {
      start=$(date +%s.%N)
      end=$(date +%s.%N)
      (( cumul+= (end-start) ))
    }
    overhead=$((cumul/100.))
    cumul=0; for i ({0..99}) {
      start=$(date +%s.%N)
      print -P $PS1 $RPS1
      end=$(date +%s.%N)
      (( cumul+= (end-start) ))
    }
    print $((cumul/100. - overhead))
    

    First, this measures the overhead which is caused by the date commands. It is done a 100 times for better statistics. Then the print -P $PS1 $RPS1 is included, also executes a 100 times, and the overhead determined in the first part is subtracted. Consecutively invocations shows that you cannot trust the 1ms digit, but the 10ms digit seems reliable. With a expected value in the order of seconds that should suffice.

But, as @Michael Kjörling already mentioned in a comment, the prompt should render in no time. So either, you should think about how to optimize your prompt or take into account, that in my experience the prompt rendering time (as in your question) is only a tiny part of the prompt display time. (I speak here mainly about the Z shell, but I assume in bash there are similar concepts.) Because there are other functions that get executed before the prompt is displayed. This is what comes immediately to my mind:

  • precmd: Executed before each prompt; use which precmd to see what it is in your case
  • if you have the option sharedhistory enabled, the file ~/.zsh_history (or whatever you named it) get's read. Especially if your home directory is on a remote filesystem, significant delay can be induced. I also observe once in a while several seconds before the prompt is displayed when the NFS server is heavily loaded.

A tool to analyze the time requirements of external programs / internal functions in detail is the zsh/zprof module, loaded by

zmodload zsh/zprof

From man zshmodules: "When loaded, the zsh/zprof causes shell functions to be profiled. The profiling results can be obtained with the zprof builtin command made available by this module."