perf(lib): optimize doom-path

Consecutive expand-file-name and recursive apply's can be expensive, so
the function has been simplified to rely more on file-name-concat. This
does change one trait about it, however: absolute paths in SEGMENTS no
long reroot the whole path, and are concatenated as ordinary file
segments.

The performance benefit is more pronounced on Emacs 28+, and will be
even more so when Doom later starts byte-compiling its libraries.
This commit is contained in:
Henrik Lissner 2022-09-06 21:07:24 +02:00
parent 89506983fe
commit cadc778a03
No known key found for this signature in database
GPG key ID: B60957CA074D39A3

View file

@ -38,19 +38,19 @@ This is used by `file-exists-p!' and `project-file-exists-p!'."
;;;###autoload ;;;###autoload
(defun doom-path (&rest segments) (defun doom-path (&rest segments)
"Constructs a file path from SEGMENTS. "Return an path expanded after concatenating SEGMENTS with path separators.
Ignores `nil' elements in SEGMENTS."
(let ((segments (remq nil segments)) Ignores `nil' elements in SEGMENTS, and is intended as a fast compromise between
file-name-handler-alist `expand-file-name' (slow, but accurate), `file-name-concat' (fast, but
dir) inaccurate)."
(while segments ;; PERF: An empty `file-name-handler-alist' = faster `expand-file-name'.
(setq segment (pop segments) (let (file-name-handler-alist)
dir (expand-file-name (expand-file-name
(if (listp segment) ;; PERF: avoid the overhead of `apply' in the trivial case. This function
(apply #'doom-path dir segment) ;; is used a lot, so every bit counts.
segment) (if (cdr segments)
dir))) (apply #'file-name-concat segments)
dir)) (car segments)))))
;;;###autoload ;;;###autoload
(defun doom-glob (&rest segments) (defun doom-glob (&rest segments)