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 09:29:15 +0000

Eli Zaretskii <[email-masked]> writes:

>> 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.
>
> It matters to me.  Timing code must be very accurate and must not
> modify the code in question, certainly not by invoking the same
> primitives that are already called by the code being times.

My point is that an extra call to `get-file-buffer' in (unless (get-file-buffer ...) ...)
does not change the profiling results - `get-file-buffer' only takes 49
samples out of 5157 (<1%). Calling `get-file-buffer' multiple times
literally make no difference in my benchmark.

> I must say that this discussion is very frustrating from my POV.  Lots
> of information, a large portion of it irrelevant, and very little
> systematical analysis of the involved code, its actual performance,
> and the conclusions with numbers to back them up.

Sorry, but I do not fully understand what you expected. I tried my best
to provide all the details of my testing during the course of this
branch of the discussion.

In particular, see
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66117#59 and later
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66117#71 where I addressed
your concern about calling `find-buffer-visiting'/`get-file-buffer'
unnecessarily in the testing code. I provided the code, the timing, and
the raw data from the profiler report.

Please, let me know if you need more.

> ... On top of that,
> gaps for a week or more between a message and a response, something
> that makes it hard to follows the discussion.  We should be able to do
> better.

I can understand the frustration, but I just have as much time as I can
allocate. I was mostly AFC for about a week and was not able to reply to
many of the Emacs-related discussions.

Also, I am used to mailing list rule that one month is allowed for a
reply (https://orgmode.org/worg/org-mailing-list.html#i-didnt-receive-an-answer).
I thought that emacs-devel is not different.

>> 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?
>
> TTTT, I don't know what to think.
>
> From my POV, there are two alternatives here:
>
>   . expose several new primitives to Lisp to make find-buffer-visiting
>     faster without changing the way we store the file-to-buffer
>     association information
>   . introduce caches or change the way file-to-buffer associations are
>     stored to speed up find-buffer-visiting
>
> What I'd like to see is that someone implements the first idea, and
> times find-buffer-visiting after that to see if it becomes fast
> enough.  Then we can discuss whether anything else is needed.

Agree. That's what I was trying to do. However, one of the new primitives
will require searching a buffer with given value of `buffer-file-number'
- the variable not defined in C. That's why my question - I can either
query buffer-local variable in generic way via `Fbuffer_local_value' or
faster, by adding `buffer-file-number' to buffer object. The latter also
makes sense in the context of `make-indirect-buffer' implementation.

>> >> 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.
>
> And that is performance-critical? in what way and in which situations?

When making a large number of edits in Org buffer. The code I am
referring to runs in `after-change-functions' and therefore should be as
fast as possible.

-- 
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>