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

From: Ihor Radchenko <[email-masked]>
Date: Wed, 13 Dec 2023 14:32:21 +0000

Eli Zaretskii <[email-masked]> writes:

>>     ;; Each call to ido-ignore-item-p LET-binds case-fold-search.
>>     ;; That is slow if there's no buffer-local binding available,
>>     ;; roughly O(number of buffers).  This hack avoids it.
>>     (setq-local case-fold-search nil)
>> 
>> But it will only solve specific problem with `find-buffer-visiting' and
>> we can always go for it if we cannot find anything better.
>
> Which other popular functions need to loop through all the buffers in
> Lisp?

Org mode... When activating the major mode, Org binds case-fold-search
many times - for each Org buffer being opened. The same with happen for
other major modes that let-bind case-fold-search during initialization.

Also, various multi-buffer search functions, like multi-occur, tag
search (etags.el), fileloop.el.

>> I thought that trying to solve a more general problem would benefit more
>> code - let-binding case-fold-search is extremely common across packages.
>
> IMO, the general way you are trying to solve this makes this a very
> hard problem with potentially Emacs-wide implications.  So we might as
> well look for easier alternatives.

The solution with Emacs-wide implications is not what I proposed, if you
are talking about breaking changes in let.
What I proposed might slow thing down because of more complex BVAR, but
that is yet to be proven. I want to try first before giving up.

> We could, for example, document the above trick, for those who need
> it.
>
> Or we could have a separate variable, which would not be a defcustom
> nor automatically buffer-local, and will have the same effect as
> case-fold-search on low-level searching and matching functions.

That's indeed another option. Also, we may introduce something similar
to `with-syntax-table' macro - `with-case-fold' and then throw a warning
if case-fold-search is let-bound directly.

> Btw, are you aware that many case-insensitive operations in Emacs
> depend also on the case table in effect, which can also be
> buffer-local?  So case-insensitive operations in Lisp can be
> unexpectedly affected by stuff like the current buffer.  One more
> reason to use them as little as possible.

... and syntax-table can be set in text properties; so not just affected
by current buffer - also by position in buffer.
Yet, it is sometimes necessary and there is no simple way around
available.

In the past, me and Mattias Engdegård even discussed a possibility to
incorporate case-fold-search flag into regexps directly
(https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63225#74)
That way, things would be less affected by the buffer-locals.

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