Here is where I plan to Blog Emacspeak tricks and introduce new features as I implement them.

Monday, August 21, 2017

Emacs Start-Up: Speeding It Up

Emacs Start-Up: Speeding It Up

1 TL;DR:

Describes my Emacs start-up file, and what I did to speed it up from
12 seconds to under 4 seconds.

2 Overview Of Steps

Byte-compile start-up files.

Temporarily increase gc-cons-threshold during startup.

Load package autoloads (not packages) during start-up.

Use eval-after-load to advantage for post-package setup.

Lexically bind file-name-handler-alist to nil if start-up
is split across many files.

Used memoization to avoid network lookup of current location during startup.

I have a large number of elpa/melpa packages installed:

(length load-path)

400

With the above, my emacs (Emacs 26 built from Git) startup time is on
average 4 seconds. This includes starting up emacspeak (including
speech servers), as well as launching a number of project-specific
shell buffers. Given that I rarely restart Emacs, the startup time is
academic — but speeding up Emacs startup did get me to clean-up my
Emacs setup.

3 Introduction

I have now used Emacs for more than 25 years, and my Emacs start-up
file has followed the same structure through this time.

The init file defines a start-up-emacs function that does the
bulk of the work.

As a first step, I added code to my start-up file to time the loading
of various modules.

4 Load Byte-Compiled Start-Up File

I keep my emacs-startup.el checked into GitHub.
My Emacs init-file is a symlink to the byte-compiled version of the
above — this is something that goes back to my time as a
grad-student at Cornell (when GitHub of course did not exist).
That is also when I originally learnt the trick of temporarily settinggc-cons-threshold to 8MB — Emacs' default is 800K.

5 Package Autoloads And eval-after-load

Over time, some of the package-specific setup files had come to
directly load packages — it just made it easier to do
package-specific setup at the time. As part of the cleanup, I updated
these to strictly load package-autoload files and wrapped post-package
setup code in eval-after-load — this is effectively the same as
using use-package.

6 Loading Files Faster

Emacs has an extremely flexible mechanism for loading files — this
means you can load compressed, encrypted or remote files without
having to worry about it. That flexibility comes at a cost — if you
are sure you dont need this flexibility during start-up, then locally
binding file-name-handler-alist to nil is a big win — in my
case, it sped things up by 50%.

7 Avoid Network Calls During Start-Up

In my case, I set calendar-latitude and calendar-longitude by
geocoding my address — geocoding is done by calling the Google Maps
API. The geocoding API is plenty fast that you normally dont notice
it — but it was adding anywhere from 1–3 seconds during
startup. Since my address doesn't change that often, I updated modulegmaps to use a memoized version. My address is set via Customize,
and the geocoded lat/long is saved to disk automatically.