Subject: Re: bug#64735: 29.0.92; find invocations are ~15x slower because of ignores

From: Michael Albinus <[email-masked]>
Date: Fri, 21 Jul 2023 15:01:56 +0200

Eli Zaretskii <[email-masked]> writes:

>> From: Ihor Radchenko <[email-masked]>
>> Cc: [email-masked], Eli Zaretskii <[email-masked]>, [email-masked],
>>  [email-masked]
>> Date: Fri, 21 Jul 2023 12:25:29 +0000
>>
>> Ihor Radchenko <[email-masked]> writes:
>>
>> > The question is: what is more costly
>> > (a) matching complex regexp && call function or
>> > (b) call function (lambda (fn) (when (and foo (match-string- ... fn)) ...))
>>
>> (benchmark-run-compiled 10000000 (string-match-p (caar file-name-handler-alist) "/path/to/very/deep/file"))
>> ;; => (1.495432981 0 0.0)
>> (benchmark-run-compiled 10000000 (funcall (lambda (fn) (and nil (string-match-p (caar file-name-handler-alist) fn))) "/path/to/very/deep/file"))
>> ;; => (0.42053276500000003 0 0.0)
>>
>> Looks like even funcall overheads are not as bad as invoking regexp search.
>
> But "nil" is not a faithful emulation of the real test which will have
> to be put there, is it?

Here are some other numbers. The definition of inhibit-remote-files and
without-remote-files is below.

--8<---------------cut here---------------start------------->8---
(length (directory-files-recursively "~/src" ""))
146121
--8<---------------cut here---------------end--------------->8---

A sufficient large directory.

--8<---------------cut here---------------start------------->8---
(benchmark-run-compiled 1 (directory-files-recursively "~/src" ""))
(38.133906724000006 13 0.5019186470000001)
(benchmark-run-compiled 1 (let (file-name-handler-alist) (directory-files-recursively "~/src" "")))
(32.944982886 13 0.5274874450000002)
--8<---------------cut here---------------end--------------->8---

There are indeed 5 sec overhead just for file name handler regexp checks.

--8<---------------cut here---------------start------------->8---
(benchmark-run-compiled 1 (without-remote-files (directory-files-recursively "~/src" "")))
(33.261659676 13 0.5338916200000003)
--8<---------------cut here---------------end--------------->8---

Removing just the Tramp file name handlers comes near to let-binding
file-name-handler-alist.

--8<---------------cut here---------------start------------->8---
(inhibit-remote-files)
nil
(benchmark-run-compiled 1 (directory-files-recursively "~/src" ""))
(34.344226758000005 13 0.5421030509999998)
--8<---------------cut here---------------end--------------->8---

And that's for the innocents, which aren't aware of Tramp overhead, and
which don't need it. As said, ~50% of Emacs users. Just adding
(inhibit-remote-files) to .emacs gives them a performance boost. W/o
touching any other code.

--8<---------------cut here---------------start------------->8---
;;;###autoload
(progn (defun inhibit-remote-files ()
  "Deactivate remote file names."
  (interactive)
  (when (fboundp 'tramp-cleanup-all-connections)
    (funcall 'tramp-cleanup-all-connections))
  (tramp-unload-file-name-handlers)
  (setq tramp-mode nil)))

;;;###autoload
(progn (defmacro without-remote-files (&rest body)
  "Deactivate remote file names temporarily.
Run BODY."
  (declare (indent 0) (debug ((form body) body)))
  `(let ((file-name-handler-alist (copy-tree file-name-handler-alist))
         tramp-mode)
     (tramp-unload-file-name-handlers)
     ,@body)))
--8<---------------cut here---------------end--------------->8---

Best regards, Michael.