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-beta packages. Oddly, the
zsh package is a more recent version than the
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
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
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/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/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
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!