(or emacs irrelevant)

Profile your Emacs start-up time

I 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.