Update 2012-10-17: The slow start up with the newer zsh
package was my own fault. In my transition to Prezto, I unintentionally removed the skip_global_compinit=1
from my .zshenv
file. The global start up scripts for zsh-beta
don’t call compinit
, but the newer ones in the zsh
package do.
Update 2012-10-16: I’m using Prezto now, but I did notice something interesting today that probably still applies to oh-my-zsh. Ubuntu 12.04 has zsh
and zsh-beta
packages. Oddly, the zsh
package is a more recent version than the zsh-beta
package.
The older zsh-beta
starts up almost five times faster:
1 2 3 4 5 6 7 8 9 |
|
For now I’m using zsh-beta
, but I will have to investigate this further.
Update 2010-04-29: All of my changes to oh-my-zsh that are listed here were pulled into the master repository last night. Just about everything here can be ignored now except for the part about adding skip_global_compinit=1
to your ~/.zshenv
if you are running Ubuntu (and possibly other distros). Adding that line still saves me almost a half second of startup time.
I’ve been very happy with zsh and oh-my-zsh except for one thing: the slow startup time. I’ve been putting up with a huge delay every time I open a new terminal, and I open terminals quite often. I did manage to solve the problem even with a total failure of my google-fu. To find the cause of the problem, I was in need of some sort of benchmark.
End of Updates
The benchmark
This turned out to be easy. I just ran /usr/bin/time zsh -i -c exit
and took note of the elapsed time. The time to beat was an abysmal 1.65 seconds. That was 0.6 seconds slower than bash
!
My first failure
First I tried to compile everything in my .oh-my-zsh
directory using zcompile
. It was a complete waste of time; there was no improvement what so ever.
My second failure
I started removing files from ~/.oh-my-zsh/lib
and ~/.oh-my-zsh/custom
. I couldn’t manage to get the startup time down below 1.2 seconds, and I was losing huge pieces of functionality. I was hoping I could pinpoint one or two particularly slow files to investigate, but that wasn’t the case.
Grasping at straws
I even tried moving my ~/.oh-my-zsh
directory to a tmpfs
partition. Of course this made no difference. The files were already cached anyway.
Getting to 0.49 seconds
I almost gave up. OK, I did give up. I didn’t find the solution until the next day…
The biggest slow down was in the system-wide zshrc
file in /etc/zsh
. On my Ubuntu 10.10 system the slow down is the call to compinit
on the second-to-last line. Following the advice of the comment and adding skip_global_compinit=1
to my ~/.zshenv
bought me over one full second.
Squeezing out a little more
There are calls to compinit
in a few files in ~/.oh-my-zsh/lib
and ~/.oh-my-zsh/plugins
. I already have a call to compinit
in one of my own scripts in ~/.oh-my-zsh/custom
, so I tried commenting out the calls in the two occurrences in ~/.oh-my-zsh/lib
(I don’t have any plugins enabled). Each one saved me about 0.07 seconds. That brings me down to 0.35 seconds, about 0.7 seconds faster than bash
!
I’m not sure why oh-my-zsh
has so many calls to compinit
. I’m pretty sure every plugin calls it once. I haven’t noticed any changes in the way completion works, and I don’t think I will. As far as I can tell, compinit
should only need to be called once.
Getting a bit more invasive
I removed all the calls to compinit
, including the one in my own script in ~/.oh-my-zsh/custom
. Then I added a single call to compinit
to the end of the `~/.oh-my-zsh/oh-my-zsh.sh’ script. This shaved off another 0.12 seconds, bringing my total down to 0.23 seconds. I don’t think there is any need for me to push things any more than this.
- Update 2010-04-19: I have included this code along with some better (and more invasive) changes in a branch on github that have my startup time down to about 0.20 seconds even with a few extra plugins enabled! There have been quite a few excellent recommendations in the comments on my pull request. I hope to see the code pulled into the trunk soon.
- Update 2010-04-24: Antonio Santos Velasco wrote an article explaining precisely how to pull down my changes from github. Thank you Antonio!