Subject: bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers

From: Ihor Radchenko <[email-masked]>
Date: Sat, 07 Oct 2023 08:25:06 +0000

Eli Zaretskii <[email-masked]> writes:

>> >> If one uses `get-file-buffer' instead of `find-buffer-visiting', the
>> >> total runtime becomes 5.1 sec - almost 4x faster.
>> >
>> > This is also not very interesting, since find-file-noselect calls
>> > get-file-buffer as well.
>> 
>> No. `find-file-noselect' calls `find-buffer-visiting'.
>
> Unless we use different Emacsen, find-file-noselect calls both
> get-file-buffer and find-buffer-visiting:
>
>       (let* ((buf (get-file-buffer filename))  <<<<<<<<<<<<<<<<<<<<<<<<<<<<

We are probably mis-communicating. My point is that `get-file-buffer' is
very fast (for my purposes). So, it does not matter as much if it is
called somewhere else and how many times.

Although, as Dmitry demonstrated, `get-file-buffer' might be slow in
certain scenarios. But let's postpone that discussion after we handle
the much slower `find-buffer-visiting'.

>> I still think that my previous conclusions are true. And I agree that
>> rewriting these expensive loops in C makes sense. Maybe two new
>> subroutines to find buffer by `buffer-file-truename' and by
>> `buffer-file-number'?
>
> Yes, that's what I had in mind.

I looked closer, and there is already `get_truename_buffer', which can
simply be exposed to Lisp.

`buffer-file-number' is a bit more tricky - it is not defined in C, but
in files.el. However, I am wondering if this variable should be moved to
C or maybe into the buffer object. `make-indirect-buffer' (defined in C)
has

      Fset (intern ("buffer-save-without-query"), Qnil);
      Fset (intern ("buffer-file-number"), Qnil);

WDYT?

>> Aside: this reminds me about obsoletion of generalized buffer-local
>> variable. AFAIU, there is currently no way to set buffer-local value in
>> buffer without setting that buffer to current. It would be nice if such
>> setting were possible, especially in performance-critical code.
>
> Maybe, but is there any performance-critical code which needs that?

For example, org-element.el needs to set buffer-local values in base
buffer of an indirect buffer every time buffer text is being edited.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>