all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* ido-switch-buffer is slow with many buffers; others are fast
@ 2020-11-14 16:34 catern
  2020-11-14 18:22 ` Stefan Monnier
  2020-11-14 23:16 ` Dmitry Gutov
  0 siblings, 2 replies; 80+ messages in thread
From: catern @ 2020-11-14 16:34 UTC (permalink / raw)
  To: emacs-devel


I recently became annoyed enough in my 1000-buffer Emacs instance to
start profiling things.

I was disappointed to find that the buffer-switching slowness I'd seen
is the fault of ido-switch-buffer.

ido-switch-buffer takes over a second before it starts accepting user
input, with this many buffers.

It appears that the slowness is completely due to ido building a list of
all buffers in ido-make-buffer-list-1. This function calls
ido-ignore-item-p on every buffer, which checks buffer names against a
regex to ignore ones with leading spaces, which seems to be fairly slow.

I tested a few other packages to see how they compared.

- switch-to-buffer, without modification: This is fast. Compared to ido,
  I believe this is because switch-to-buffer ultimately uses read-buffer
  and internal-complete-buffer to read the buffer, which are implemented
  in C and presumably have been well-optimized. ido doesn't use those.

- switch-to-buffer with icomplete-mode: This is also fast, I suppose
  because it also uses read-buffer and internal-complete-buffer, and
  just customizes completion, unlike ido-mode.

- switch-to-buffer with fido-mode: This is also fast, again for the same
  reasons as icomplete-mode.

- iswitchb-mode: This is fairly fast - faster than ido-mode. But, it
  still has a noticeable delay. Like ido, it doesn't use read-buffer,
  and it builds a list of all buffers. Relative to ido, it seems to have
  a more efficient (and less generic) implementation of ignoring
  irrelevant buffers, which explains its speed-up. This is a bit
  unfortunate since iswitchb-mode has been deprecated in favor of
  ido-mode.

I also tried some third-party packages.

- helm: Slow. Looks like it builds a list of all buffers. (Note that
  helm is not in GNU ELPA, but is quite popular.)

- ivy: Fast. It uses read-buffer and only customizes completion.
  Notably, ivy seems to have many, if not a superset, of the features of
  ido-mode. (ivy is in GNU ELPA)

What is the solution? It seems to me that there are two candidates:

1. Given that ivy has a similar feature set to ido, and uses
   read-buffer, and is fast, it seems that it should be possible to make
   ido use read-buffer without loss of functionality.

2. ido should be deprecated or discouraged in favor of ivy, possibly as
   part of including ivy into core Emacs.

Discovering this inefficiency of ido (which probably applies to other
ido functions, since they have similar implementations) is fairly
disappointing to me, because it's frequently recommended to new
users.

There have been many proposals to turn ido on by default in Emacs.
Alas, given the current state of ido's performance, it seems to me to be
clearly unacceptable to turn ido on by default.




^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2020-12-01 18:10 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-14 16:34 ido-switch-buffer is slow with many buffers; others are fast catern
2020-11-14 18:22 ` Stefan Monnier
2020-11-14 20:06   ` sbaugh
2020-11-14 23:00     ` Stefan Monnier
2020-11-14 23:16 ` Dmitry Gutov
2020-11-15  0:19   ` Spencer Baugh
2020-11-15 15:15     ` Stefan Monnier
2020-11-15 20:49       ` Spencer Baugh
2020-11-15 23:58         ` Arnold Noronha
2020-11-19 15:38         ` [PATCH 00/10] Speeding up DEFVAR_PER_BUFFER (Was: ido-switch-buffer is slow) Spencer Baugh
2020-11-19 17:29           ` [PATCH 00/10] Speeding up DEFVAR_PER_BUFFER Stefan Monnier
2020-11-22  2:34           ` [PATCH v2 00/16] " Spencer Baugh
2020-11-22  2:34             ` [PATCH v2 01/16] Add a test for let-binding unwinding Spencer Baugh
2020-11-25 20:53               ` Stefan Monnier
2020-11-30 17:31                 ` Spencer Baugh
2020-12-01 16:44               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 02/16] Assert not local-variable-p after setq in let_default binding Spencer Baugh
2020-11-25 20:54               ` Stefan Monnier
2020-12-01 16:45               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 03/16] Stop checking the constant default for enable_multibyte_characters Spencer Baugh
2020-11-25 20:57               ` Stefan Monnier
2020-12-01 16:52               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 04/16] Take buffer field name in DEFVAR_PER_BUFFER Spencer Baugh
2020-12-01 16:56               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 05/16] Add BVAR_DEFAULT for access to buffer defaults Spencer Baugh
2020-12-01 17:00               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 06/16] Use bset_* functions instead of BVAR Spencer Baugh
2020-12-01 17:12               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 07/16] Take offset not idx in PER_BUFFER_VALUE_P Spencer Baugh
2020-12-01 17:20               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 08/16] Combine unnecessarily separate loops in buffer.c Spencer Baugh
2020-12-01 17:22               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 09/16] Add and use BUFFER_DEFAULT_VALUE_P Spencer Baugh
2020-12-01 17:24               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 10/16] Add and use KILL_PER_BUFFER_VALUE Spencer Baugh
2020-12-01 17:26               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 11/16] Assert that PER_BUFFER_IDX for Lisp variables is not 0 Spencer Baugh
2020-12-01 17:32               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 12/16] Rearrange set_internal for buffer forwarded symbols Spencer Baugh
2020-12-01 17:35               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 13/16] Get rid of buffer_permanent_local_flags array Spencer Baugh
2020-11-22 16:16               ` Eli Zaretskii
2020-12-01 17:39               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 14/16] Remove unnecessary Qunbound check Spencer Baugh
2020-12-01 17:40               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 15/16] Remove local_flags array in struct buffer Spencer Baugh
2020-11-22 20:04               ` Stefan Monnier
2020-12-01 17:57               ` Eli Zaretskii
2020-11-22  2:34             ` [PATCH v2 16/16] Remove usage of buffer_local_flags Spencer Baugh
2020-12-01 18:05               ` Eli Zaretskii
2020-11-22 11:19             ` [PATCH v2 00/16] Speeding up DEFVAR_PER_BUFFER Kévin Le Gouguec
2020-11-22 16:12             ` Eli Zaretskii
2020-11-22 16:28               ` Spencer Baugh
2020-11-22 17:13                 ` Eli Zaretskii
2020-11-29 17:41                   ` Spencer Baugh
2020-11-30 18:32                     ` Eli Zaretskii
2020-11-30 20:11                       ` Spencer Baugh
2020-11-30 22:10                         ` Stefan Monnier
2020-11-30 22:26                           ` Andrea Corallo via Emacs development discussions.
2020-12-01 15:15                           ` Eli Zaretskii
2020-12-01 15:56                             ` Stefan Monnier
2020-12-01 15:10                         ` Eli Zaretskii
2020-12-01 15:20                           ` Spencer Baugh
2020-12-01 16:01                           ` Stefan Monnier
2020-12-01 16:16                             ` Eli Zaretskii
2020-12-01 18:10                       ` Eli Zaretskii
2020-11-22 20:11                 ` Stefan Monnier
2020-11-19 15:38         ` [PATCH 01/10] Take buffer field name in DEFVAR_PER_BUFFER Spencer Baugh
2020-11-19 15:38         ` [PATCH 02/10] Add bset_save_length and use it Spencer Baugh
2020-11-19 15:38         ` [PATCH 03/10] Use bset_last_selected_window everywhere Spencer Baugh
2020-11-19 15:38         ` [PATCH 04/10] Use bset_enable_multibyte_characters everywhere Spencer Baugh
2020-11-19 15:38         ` [PATCH 05/10] Add BVAR_DEFAULT for access to buffer defaults Spencer Baugh
2020-11-19 15:38         ` [PATCH 06/10] Disallow using BVAR as an lvalue Spencer Baugh
2020-11-19 15:38         ` [PATCH 07/10] Reorder buffer.h for upcoming rework of BVAR Spencer Baugh
2020-11-19 15:38         ` [PATCH 08/10] Make cache_long_scans buffer-local when setting it Spencer Baugh
2020-11-19 15:38         ` [PATCH 09/10] Access buffer_defaults in BVAR if there's no local binding Spencer Baugh
2020-11-19 18:08           ` Stefan Monnier
2020-11-19 18:21             ` Eli Zaretskii
2020-11-19 15:38         ` [PATCH 10/10] Don't iterate over all buffers in set_default_internal Spencer Baugh
2020-11-19 18:21           ` Stefan Monnier

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.