4

short version: How can I profile each rendering of a zsh prompt?

long version: I've recently came across a plugin (rupa/z) that, when installed, hit my zsh prompt rendering time by a noticeable amount. I want to measure how much of an impact this plugin has inflicted, when loaded, on my zsh prompt rendering time.

When I say prompt rendering time, I'm not refering to amount of time that it takes for the first zsh prompt to appear when I issue, for an example, exec zsh (that is achieved by issuing time zsh -i -c "print -n").

I'm talking about the time that it takes for zsh to give me another prompt once that it is fully loaded. In other words, I want to achieve this:

~ $ ls (when i hit enter, start counting)
code/ notes/ file.txt
~ $ (stop counting when this prompt appears. show me elapsed time)

can it be done?

5

Update: Use zle-line-init (Thanks to Gilles for the hint)

Not exactly profiling, but from the text in your question it seems, that you are primarily interested in gauging how much delay the plugin entails.

One way to get this estimate is by utilizing the precmd hook, which is run every time just before the prompt is rendered, and the zle-line-init widget, which is run each time the line editor starts up.

The following should do the trick. Just add it to your ~/.zshrc.

# set type of SECONDS and start to float to increase precision
typeset -F SECONDS start 

# define precmd hook function
precmd () {
    # save time since start of zsh in start
    start=$SECONDS
}

# define zle-line-init function
zle-line-init () {
     # print time since start was set after prompt
     PREDISPLAY="[$(( $SECONDS - $start ))] "
}
# link the zle-line-init widget to the function of the same name
zle -N zle-line-init

With that, the elapsed time for each prompt will be written in brackets after the prompt, like this:

 prompt% [0.00013200000000779255] 

Note: if either the precmd function or the zle-line-init function are already defined, you need to add the respective function bodies to the existing definitions. For precmd, you need to put it at the very start, and for zle-line-init at the very end, as the existing contents of both might have influence on the time it takes to render the prompt (or what looks like the prompt).

  • To find out whether precmd is already defined, run whence -c precmd.
  • For zle-line-init run zle -lL zle-line-init. If it is already set, it will print a line like

    zle -N zle-line-init _zsh_highlight_widget_zle-line-init
    

    where the last word is the name of the linked function (it does not need to have the same name).

  • 2
    You can run code when the prompt is printed by defining the zle-line-init widget (check the manual). But all this only benchmarks the prompt, it doesn't profile it. – Gilles 'SO- stop being evil' Jul 13 '16 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.