homebrew

Decreasing my zsh startup time

Sometimes I noticed a new shell's startup being really slow. This annoyed me from time to time, so today I decided to try some optimizations.

Measure

I measured my startup time in a rather crude way. I'm loading my zsh configuration files like in the following snippet:

I relied on subjective analysis and changed it to the following code:

What this does is print the path to the configuration file, load it and then wait for a return key press to load the next file.

With this, I could start a new shell and see which files are slow to load.

Remove brew --prefix

From the measurements I noticed that the slow files were those where I load some tools via homebrew. I load for example grc and hub that way. I used this approach for my PATH as well with PHP and the Android SDK.

I then timed an execution of brew --prefix hub and got the following result:

It takes around 0.15 seconds to load the path prefix for hub! If you do that a couple of times in your zsh configuration, it sums up to a lot of time.

I then changed all the occurences to the absolute path, as it's mostly just /usr/local/opt and the package name. It's not as flexible anymore, but that's a small price for a faster shell startup time.

Change rbenv initialization

The one other file that loaded slowly was my rbenv initialization. It calls the following snippet:

A bit of googling revealed the --no-rehash option which prevents an expensive rehashing of ruby and rubygems executables when loading rbenv. You can always rehash later with rbenv rehash.

So I measured it again, to be sure it helps.

As you can see, --no-rehash sped it up quite a bit.
As a side-effect, I learned how to measure code blocks in zsh ;-)

Results

With these changes, I decreased my zsh startup time from 1.5s to 0.6s.

It's nice to see that two small changes can speed up an application I use every day.
For more information, you can see my full zsh configuration (along with my other dotfiles) on GitHub.

Read more »