Profile your Emacs start-up time
24 Feb 2015I bet I could compete for the shortest ~/.emacs
ever:
(load "~/Dropbox/source/site-lisp/init")
However, it being one line doesn't make it start up any faster.
Here's what I have in my Makefile beside init.el
:
profile:
emacs -Q -l git/profile-dotemacs/profile-dotemacs.el \
--eval "(setq profile-dotemacs-file \
(setq load-file-name \"$(abspath init.el)\"))" \
-f profile-dotemacs
The package that I'm using, profile-dotemacs.el comes from David Engster, one of the major contributors to CEDET, so you know it's got to be good. Once you launch it as I showed above, it will give you the times that various sections took to load in an overlay.
On very sunny days I can almost get Emacs to start under one second,
although when I checked just now, it turned out to be 1.20s
. I
value short start up time very highly, since due to my messing with
Elisp, the Emacs global state can become so messed up that it's a lot
faster to just restart it, rather than spend 10 minutes surgically
restoring the state. And, of course, it's a bonus for using Emacs on a
laptop, which I do at home.
I've used two methods to shorten the boot time, I'll describe them below.
use-package
:idle
option
This one is a big time saver, since org-mode
just takes so long to load:
(use-package org
:defer t
:idle (require 'oleh/org))
I'm cautious not to abuse :idle
, since if it happens that I start
Emacs and start frantically typing all over the place, Emacs will
never get to be idle and the :idle
statements won't load. So I only
use it for org
and one or two other things.
autoloading stuff
Here's some helper code for this:
(defun update-all-autoloads ()
(interactive)
(cd emacs-d)
(let ((generated-autoload-file
(expand-file-name "loaddefs.el")))
(when (not (file-exists-p generated-autoload-file))
(with-current-buffer (find-file-noselect
generated-autoload-file)
(insert ";;")
(save-buffer)))
(mapcar #'update-directory-autoloads
'("" "oleh" "oleh/modes"))))
Here, emacs-d
is the directory of my init.el
.
The directory modes
contains 44 Elisp files for each major mode or package that I customize.
For instance, here are the contents of Info.el
:
(define-key Info-mode-map "j" 'ora-para-down)
(define-key Info-mode-map "k" 'ora-para-up)
(define-key Info-mode-map "v" 'recenter-top-bottom)
(define-key Info-mode-map "h" 'backward-char)
(define-key Info-mode-map "l" 'forward-char)
(define-key Info-mode-map "w" 'forward-word)
(define-key Info-mode-map "b" 'backward-word)
(define-key Info-mode-map "a" 'beginning-of-line)
(define-key Info-mode-map "e" 'end-of-line)
(define-key Info-mode-map "A" 'beginning-of-buffer)
(define-key Info-mode-map "E" 'end-of-buffer)
;;;###autoload
(defun oleh-Info-hook ())
This is one of the simpler ones, I think it would take around a week
of posts to cover what I have in magit.el
. The file Info.el
never
gets loaded until I open a buffer in Info-mode
.
Here's what gets loaded every time:
(load (concat emacs-d "loaddefs.el") nil t)
;; ...
(add-hook 'Info-mode-hook 'oleh-Info-hook)
My loaddefs.el
is just over 1000 lines and is automatically
generated by update-all-autoloads
. And here are the lines in
loaddefs.el
responsible for loading Info.el
:
(autoload 'oleh-Info-hook "oleh/modes/Info" "\
\(fn)" nil nil)
So the statements above are cheap to load. Actually, the largest chunk of my start up time, 28 percent, is taken by:
(require 'eclipse-theme)
I don't know why it takes so long to call custom-theme-set-faces
, it's a mystery.