Subject: Re: bug#41029: Improve ido-switch-buffer performance when many buffers are open

From: Arnold Noronha <[email-masked]>
Date: Sat, 2 May 2020 11:26:36 -0700

Actually, I realized this could be cleaner. Nicer patch attached.

--Arnold

On Sat, May 02, 2020 at 10:05:21AM -0700, Arnold Noronha wrote:
>
> On Sat, May 02, 2020 at 08:40:55AM -0700, Arnold Noronha wrote:
> > +         (flet ((inner ()
>
>From 3dc513bc01decf9774f9ce5974abca30cbd71805 Mon Sep 17 00:00:00 2001
From: Arnold Noronha <[email-masked]>
Date: Sat, 2 May 2020 11:24:22 -0700
Subject: [PATCH] Use a temporary-buffer before calling ido-ignore-item-p
 multiple times

And locally set CASE-FOLD-SEARCH. Setting CASE-FOLD-SEARCH 1000s of
times if CASE-FOLD-SEARCH is not locally set is super slow because it
would have to update the bindings in each buffer (or, that is my
understanding. See the warning at:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Intro-to-Buffer_002dLocal.html#Intro-to-Buffer_002dLocal)
---
 lisp/ido.el | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/lisp/ido.el b/lisp/ido.el
index 81883402ad..22b3729097 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -3407,13 +3407,18 @@ ido-make-merged-file-list
 
 (defun ido-make-buffer-list-1 (&optional frame visible)
   "Return list of non-ignored buffer names."
-  (delq nil
-	(mapcar
-	 (lambda (x)
-	   (let ((name (buffer-name x)))
-	     (if (not (or (ido-ignore-item-p name ido-ignore-buffers) (member name visible)))
-		 name)))
-	 (buffer-list frame))))
+  (with-temp-buffer
+    ;; 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)
+    (delq nil
+	  (mapcar
+	   (lambda (x)
+	     (let ((name (buffer-name x)))
+	       (if (not (or (ido-ignore-item-p name ido-ignore-buffers) (member name visible)))
+		   name)))
+	   (buffer-list frame)))))
 
 (defun ido-make-buffer-list (default)
   "Return the current list of buffers.
-- 
2.20.1