Solvedpowerlevel9k Caching to speed up prompt generation
✔️Accepted Answer
By the way, for those of you who don't follow /r/zsh, Powerlevel10k now works on all major platforms (Mac, Linux, FreeBSD and WSL). It's backward-compatible with Powerlevel9k configuration and it's 50 times faster.
If you are currently using Powerlevel9k, type this and see how fast your shell will become while still looking the same:
git clone https://github.com/romkatv/powerlevel10k.git /tmp/powerlevel10k
source /tmp/powerlevel10k/powerlevel10k.zsh-theme
(When you are done playing, rm -rf /tmp/powerlevel10k
and exit zsh.)
You can find other options for trying out the theme in the docs.
Other Answers:
In case anyone is also bothered by how slow the vcs/git prompt is, I've managed to speed it up by a large margin. On Linux my whole prompt (which includes vcs
as well as all the prompts I listed in the previous comment) renders in 50ms when I'm in a git repo with 1k files. In a large repo such as Linux kernel, it renders in 300ms -- too slow for my taste. I added an option to disable scanning dirty files for repos above certain size and set it at 4k files in my .zshrc
. With this option my prompt renders in 150ms when in Linux repo. The prompt also uses color-coding to signal that it didn't scan for dirty files. Finally vcs prompt is fast enough to be usable for me!
The trick was to write a custom C binary that prints everything we need to know about a git repo. It's much faster than calling git
multiple times, which spawns a dozen processes with accompanying pipes and repeats many actions unnecessarily -- such as scanning parent folders in search of .git
. And also caching, of course, to make rendering itself fast. The C code is in https://github.com/romkatv/gitstatus. The ZSH code is in the same branch as caching: https://github.com/romkatv/powerlevel9k/tree/caching.
If anyone wants to give it a try with their own master-based setup (especially if it's sluggish), here's a non-committal way to do it.
# Enable caching of parts of the prompt to make rendering much faster.
POWERLEVEL9K_USE_CACHE=true
# Enable alternative implementation for the vcs prompt. It's much faster but it only supports git.
# Tell it to not scan for dirty files in repos with over 4k files.
POWERLEVEL9K_VCS_STATUS_COMMAND="/tmp/gitstatus --dirty-max-index-size=4096"
wget https://github.com/romkatv/gitstatus/releases/latest/download/gitstatus -P /tmp
chmod +x /tmp/gitstatus
# Adjust this path depending on where you normally source powerlevel9k.zsh-theme from.
POWERLEVEL9K_INSTALLATION_DIR=~/.oh-my-zsh/custom/themes/powerlevel9k
source <(curl -f https://raw.githubusercontent.com/romkatv/powerlevel9k/caching/powerlevel9k.zsh-theme)
Then see if your current shell feels more responsive. No permanent changes are done to your setup, so once you exit zsh you are back to business as usual.
I can vouch for the following prompts being fast in the patched version:
root_indicator
dir_writable
dir
status
command_execution_time
background_jobs
time
vcs
tl;dr: I patched P9K to reduce my zsh prompt drawing latency by over 10x. Is this something you would be interested in adopting?
I recently started using Windows Subsystem for Linux and discovered that my standard Linux zsh environment was so slow, it was barely usable. It was taking over a second to draw a prompt after each command. Granted, it was never snappy even on Linux but it was at least manageable.
I've spent some time profiling and optimizing the code and the results look promising. On each prompt P9K performs a lot of computation and over 90% of it is the same as in the last prompt. I implemented simple caching to avoid recomputing things and now my prompts get rendered in less than 100ms on WSL -- over 10x reduction in latency. They are now also blazingly fast on Linux.
I'm not an expert in zsh, so I didn't want to open a PR right away. I also didn't write any tests. If there is interest in this type of improvements, the code is here: https://github.com/romkatv/powerlevel9k/tree/caching. The code adds a general caching mechanism for anything that prompt generators might want to cache between calls, and then applies it to
left_prompt_segment
andright_prompt_segment
for nice latency reduction across the board. It also contains optimizations for all prompt generators that I personally use and that were showing up on my profile as being slow. Let me know what you want me to do. Open a PR, sign something so that you can pull the code, go away, something else?P.S.
My
.zshrc
is here: https://github.com/romkatv/dotfiles-public/blob/master/.zshrc.