In the choice of editors to use I finally decided to go with Emacs. (I really like Vim, too!) As I wade back into the deep end of the software and databases pool Emacs looks like a good fit for me. I like the idea of being able to work with Python, SQL, Matlab, check my email, write blog posts and organize my life all from one application. Especially, now that I have some key bindings that make sense for me!
With that settled I got hit by the start up time optimization obsession. There’s something very attractive about vim/vi’s instant start up time. As I followed the path of spending hours to cut 1/2 second I discovered something. I was learning to use Emacs better while learning how to make it start fast.
Two Basic Approaches For A Faster Starting Emacs
In my quest for a fast starting Emacs I came across two basic approaches. Optimize various aspects of your .emacs or run Emacs as a service (see Resources below.)
Which works pretty well. This approach is definitely fast! All the time consuming parts of starting are done when your computer boots. The only thing I didn’t like was that the buffers were the same for each frame started. I could probably adapt. Maybe down the road I’ll try it again.
The second approach is what I’m lumping all the different ways to optimize and construct your .emacs file. In this approach a tool I found really helpful is Profile-DotEmacs (see Resources below.) Profile-dotemacs highlights the slowest parts of your .emacs load process including garbage collection (GC). I also used emacs-init M-x emacs-init for comparison.
What popped up immediately was how (require ‘) really slowed down things. Lazy loading to the rescue. Using autoload and with-eval-after-load in your .emacs you can defer loading packages until later in the startup process or when they are needed. Using Emacs Package is handy here because it handles autoload for you.
There’s a trade off because package-initialize takes quite a while relatively to load. Using use-package is supposed to help with this by loading only specific packages. Except it looks like you miss out on some of the convenience of allowing Package to manage things. I’m still working out whether or not I want to give up the convenience and use use-package. Sounds pretty effective though.
Here are my start up times. for Emacs 24.5 . Start ups times were checked when the cache was cold right after booting the computer and after Emacs had been loaded a few times.
|Profile-DotEmacs||1.71 sec||0.49 sec|
|emacs-init||4.1 sec||1.5 sec|
System details: GNU Emacs 24.5.1 (x86_64-redhat-linux-gnu, GTK+ Version 3.17.8) with ~ 30 packages. Toshiba Satellite, AMD A6-3420M APU , 6Gig ram running Fedora 23
The top 3 things that made my Emacs start faster:
- Deleting packages! Packages were loading that I didn’t need or were redundant functionally with other packages.
- Minimize use of (require ‘…) I was using require for packages that were already being loaded by default! All I needed to do was adjust settings for those packages with Emacs. Saved quite a bit of time. Autoload and eval-after-loading are also helpful.
- Raised the garbage collection (GC) threshold from 800k to 20M. Emacs garbage collection happens when the threshold is reached. Raising the limit saves a lot of time that was spent on GC. At the end of my .emacs I set it back to the default value.
There were some other approaches I used or at least experimented with during this process. Offloading some the GUI settings to X, adjusting cache pressure, and a couple others were interesting to experiment with but didn’t give as much return.
My current major bottlenecks:
- Loading the theme.
- Whatever happens after .emacs loads. I turned off default.el which loads after .emacs. Somehow working with .Xresources might be helpful here though I’m not sure I want to customize outside of Emacs.
I’m happy with the time I’ve spent reducing load time for Emacs. Some benefits I got from the exercise:
- I learned a little about how Emacs works under the covers. Including see lots of code other people have written is very helpful in beginning to develop an intuition regarding Emacs.
- And I got to practice using Emacs to make Emacs faster. My Emacs keyboard skills have definitely improved and I’ve got some reasonable key bindings to work with now.
- Lastly, there’s a psychological factor involved in start up time for me. I feel better not having to wait. Even 1 second can interrupt flow if I stop and restart Emacs. Granted, I can go all day before shutting down. Knowing I can restart fast though does feel good.