]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve performance of `file-truename' (bug#70036)
authorIhor Radchenko <yantar92@posteo.net>
Tue, 30 Apr 2024 11:27:04 +0000 (14:27 +0300)
committerEshel Yaron <me@eshelyaron.com>
Mon, 6 May 2024 16:33:47 +0000 (18:33 +0200)
* lisp/files.el (file-truename): Avoid repetitive calls to
`file-name-nondirectory'.  These calls contribute
significantly to CPU time.  See the benchmarks in
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=70036#47

(cherry picked from commit bf00762745c07816e7a9c64e0fce037039852971)

lisp/files.el

index 6c9b51793ef20ac79da39b359971ac627919fef9..f3a13d95d778fbe47ff5f1004190a0eaa0410807 100644 (file)
@@ -1517,27 +1517,28 @@ containing it, until no links are left at any level.
                        (new (file-name-as-directory (file-truename dirfile counter prev-dirs))))
                    (setcar prev-dirs (cons (cons old new) (car prev-dirs)))
                    (setq dir new))))
-           (if (equal ".." (file-name-nondirectory filename))
-               (setq filename
-                     (directory-file-name (file-name-directory (directory-file-name dir)))
-                     done t)
-             (if (equal "." (file-name-nondirectory filename))
-                 (setq filename (directory-file-name dir)
-                       done t)
-               ;; Put it back on the file name.
-               (setq filename (concat dir (file-name-nondirectory filename)))
-               ;; Is the file name the name of a link?
-               (setq target (file-symlink-p filename))
-               (if target
-                   ;; Yes => chase that link, then start all over
-                   ;; since the link may point to a directory name that uses links.
-                   ;; We can't safely use expand-file-name here
-                   ;; since target might look like foo/../bar where foo
-                   ;; is itself a link.  Instead, we handle . and .. above.
-                   (setq filename (files--splice-dirname-file dir target)
-                         done nil)
-                 ;; No, we are done!
-                 (setq done t))))))))
+            (let ((filename-no-dir (file-name-nondirectory filename)))
+             (if (equal ".." filename-no-dir)
+                 (setq filename
+                       (directory-file-name (file-name-directory (directory-file-name dir)))
+                       done t)
+               (if (equal "." filename-no-dir)
+                   (setq filename (directory-file-name dir)
+                         done t)
+                 ;; Put it back on the file name.
+                 (setq filename (concat dir filename-no-dir))
+                 ;; Is the file name the name of a link?
+                 (setq target (file-symlink-p filename))
+                 (if target
+                     ;; Yes => chase that link, then start all over
+                     ;; since the link may point to a directory name that uses links.
+                     ;; We can't safely use expand-file-name here
+                     ;; since target might look like foo/../bar where foo
+                     ;; is itself a link.  Instead, we handle . and .. above.
+                     (setq filename (files--splice-dirname-file dir target)
+                           done nil)
+                   ;; No, we are done!
+                   (setq done t)))))))))
     filename))
 
 (defun file-chase-links (filename &optional limit)