起動時間を短くする・最小init-loader実装

設定を見直し中 - すぎゃーんメモ シリーズ。
起動時に読み込むファイルを分割して整理するためにinit-loader.elを使用していたけど、

  • benchmark
  • 環境による読み込みファイル名の振り分け
  • ロギング

など、諸々便利なことをしてくれている。これらを使わずに、

だけに機能を絞って、それだけを行う処理を自分で書いたらどうなるか。

;; init loader
(defgroup init-loader nil
  "init loader"
  :group 'init-loader)
(defcustom init-loader-directory (expand-file-name "~/.emacs.d/inits")
  "default directory"
  :type 'directory
  :group 'init-loader)
(defcustom init-loader-default-regexp "\\(?:^[[:digit:]]\\{2\\}-.*\.elc?\\)$"
  "default filename regexp"
  :type 'regexp
  :group 'init-loader)
(let* ((targets '())
       (init-dir init-loader-directory)
       (load-path (cons init-dir load-path))
       (files (directory-files init-dir t)))
  (while files
    (let ((file (file-name-nondirectory (car files))))
      (and (string-match init-loader-default-regexp file)
           (cond ((string-match "\.el$" file)
                  (or (locate-library (concat file "c"))
                      (add-to-list 'targets file)))
                 ((string-match "\.elc$" file)
                  (add-to-list 'targets file))
                 (t))))
    (setq files (cdr files)))
  (setq targets (sort targets 'string<))
  (while targets
    (condition-case e
        (load (file-name-sans-extension (car targets)))
      (error (message "%s" e)))
    (setq targets (cdr targets))))

clマクロ使わずに書いてみたらすっごい汚くなったけど…

いちおう今inits以下に13個くらいファイル置いてある自分の環境では、init-loader.elからコレに切り替えることで起動時間が400msくらい速くなった。

追記

clマクロ使うとこんなカンジ…?

(eval-when-compile (require 'cl))
(let* ((init-dir init-loader-directory)
       (load-path (cons init-dir load-path))
       (files (directory-files init-dir t))
       (targets (loop for file in (directory-files init-dir t)
                      when (let ((file (file-name-nondirectory file)))
                             (and (string-match init-loader-default-regexp file)
                                  (or (and (string-match "\.el$" file)
                                           (or (not (locate-library (concat file "c")))))
                                      (string-match "\.elc$" file))))
                      collect file into ret
                      finally return (sort ret 'string<))))
  (dolist (target targets)
    (condition-case e
        (load (file-name-sans-extension target))
      (error (message "%s" e)))))

loopの書き方が色々ありすぎて使いこなせない ><