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