[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large nu
From: |
Ihor Radchenko |
Subject: |
bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers |
Date: |
Fri, 15 Dec 2023 11:01:53 +0000 |
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> Do I understand correctly that what is needed to implement your
>> suggestion is
>>
>> 1. Remove case_fold_search_ slot from buffer objects
>> 2. Use DEFVAR_LISP for case-fold-search
>> 3. Declare case-fold-search buffer-local
>> 4. Replace BVAR(...) references in C with Vcase_fold_search
>
> Yes (assuming that 3 refers to the use of `make-variable-buffer-local`).
See the attached patch.
I used my `find-buffer-visiting' benchmark
(dolist (file (directory-files "/tmp/test/" t "txt"))
(find-file-noselect file))
Without the patch: 10.3 sec
With the patch: 7.0 sec
Without the patch, the reverse profiler tree is
2728 26% Automatic GC
1187 11% + abbreviate-file-name ;; <---
1080 10% + inhibit-local-variables-p ;; <---
913 8% + uniquify-rationalize-file-buffer-names
816 7% + find-buffer-visiting
547 5% + locate-dominating-file
With the patch, the `abbreviate-file-name' and
`inhibit-local-variables-p' no longer appear on top
2559 35% Automatic GC
892 12% + uniquify-rationalize-file-buffer-names
704 9% + find-buffer-visiting
473 6% + locate-dominating-file
295 4% + dir-locals--all-files
241 3% + generate-new-buffer
219 3% + file-truename
169 2% + inhibit-local-variables-p
128 1% + abbreviate-file-name
>From fb7677be03e8c49d6a549f0d993b4df6f0ea404d Mon Sep 17 00:00:00 2001
Message-ID:
<fb7677be03e8c49d6a549f0d993b4df6f0ea404d.1702638101.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Fri, 15 Dec 2023 11:47:45 +0100
Subject: [PATCH] Improve performance let-binding `case-fold-search'
(bug#66117)
* src/buffer.h: Remove case_fold_search_ buffer object slot.
* src/buffer.c (bset_case_fold_search): Remove - no longer needed.
(init_buffer_once): Remove removed buffer slot init.
(syms_of_buffer): Use DEFVAR_LISP to define `case-fold-search' and
declare it buffer-local.
* src/minibuf.c (syms_of_minibuf): Remove DEFSYM call for
`case-fold-search' symbol. It now lives in `syms_of_buffer'.
* src/editfns.c (Fcompare_buffer_substrings):
(Fchar_equal):
* src/search.c (looking_at_1):
(string_match_1):
(search_command):
(Fre__describe_compiled): Adjust C queries to `case-fold-search' value
to use C globals instead of BVAR macro.
* doc/lispref/internals.texi (Buffer Internals): Do not list
`case_fold_search' slot.
See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66117#259
When used as buffer slot, let-binding `case-fold-search' would scale
with the number of live buffers and can be slow. This change makes
let-binding much faster at the cost of slightly slower `set-buffer'.
---
doc/lispref/internals.texi | 1 -
src/buffer.c | 17 ++++++-----------
src/buffer.h | 1 -
src/editfns.c | 4 ++--
src/minibuf.c | 1 -
src/search.c | 10 +++++-----
6 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 1fba683223e..4b4edda6d46 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -2519,7 +2519,6 @@ Buffer Internals
@item mode_line_format
@itemx header_line_format
-@itemx case_fold_search
@itemx tab_width
@itemx fill_column
@itemx left_margin
diff --git a/src/buffer.c b/src/buffer.c
index 12f226d8249..919c470d9e5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -210,11 +210,6 @@ bset_buffer_file_coding_system (struct buffer *b,
Lisp_Object val)
b->buffer_file_coding_system_ = val;
}
static void
-bset_case_fold_search (struct buffer *b, Lisp_Object val)
-{
- b->case_fold_search_ = val;
-}
-static void
bset_ctl_arrow (struct buffer *b, Lisp_Object val)
{
b->ctl_arrow_ = val;
@@ -4692,7 +4687,6 @@ init_buffer_once (void)
XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, abbrev_mode), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, overwrite_mode), idx); ++idx;
- XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx);
++idx;
@@ -4785,7 +4779,6 @@ init_buffer_once (void)
bset_tab_line_format (&buffer_defaults, Qnil);
bset_abbrev_mode (&buffer_defaults, Qnil);
bset_overwrite_mode (&buffer_defaults, Qnil);
- bset_case_fold_search (&buffer_defaults, Qt);
bset_auto_fill_function (&buffer_defaults, Qnil);
bset_selective_display (&buffer_defaults, Qnil);
bset_selective_display_ellipses (&buffer_defaults, Qt);
@@ -5215,10 +5208,6 @@ syms_of_buffer (void)
doc: /* Non-nil if Abbrev mode is enabled.
Use the command `abbrev-mode' to change this variable. */);
- DEFVAR_PER_BUFFER ("case-fold-search", &BVAR (current_buffer,
case_fold_search),
- Qnil,
- doc: /* Non-nil if searches and matches should ignore
case. */);
-
DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
Qintegerp,
doc: /* Column beyond which automatic line-wrapping should
happen.
@@ -5951,6 +5940,12 @@ Functions (implicitly) running this hook are
`get-buffer-create',
This is the default. If nil, auto-save file deletion is inhibited. */);
delete_auto_save_files = 1;
+ DEFVAR_LISP ("case-fold-search", Vcase_fold_search,
+ doc: /* Non-nil if searches and matches should ignore case. */);
+ Vcase_fold_search = Qt;
+ DEFSYM (Qcase_fold_search, "case-fold-search");
+ Fmake_variable_buffer_local (Qcase_fold_search);
+
DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook,
doc: /* Normal hook to run in the new buffer at the end of
`make-indirect-buffer'.
diff --git a/src/buffer.h b/src/buffer.h
index b2bd15657dc..399c6585158 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -379,7 +379,6 @@ #define BVAR(buf, field) ((buf)->field ## _)
/* Values of several buffer-local variables. */
/* tab-width is buffer-local so that redisplay can find it
in buffers that are not current. */
- Lisp_Object case_fold_search_;
Lisp_Object tab_width_;
Lisp_Object fill_column_;
Lisp_Object left_margin_;
diff --git a/src/editfns.c b/src/editfns.c
index 49d552c4a75..aa410ea7091 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1785,7 +1785,7 @@ DEFUN ("compare-buffer-substrings",
Fcompare_buffer_substrings, Scompare_buffer_
register EMACS_INT begp1, endp1, begp2, endp2, temp;
register struct buffer *bp1, *bp2;
register Lisp_Object trt
- = (!NILP (BVAR (current_buffer, case_fold_search))
+ = (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_canon_table) : Qnil);
ptrdiff_t chars = 0;
ptrdiff_t i1, i2, i1_byte, i2_byte;
@@ -4367,7 +4367,7 @@ DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
if (XFIXNUM (c1) == XFIXNUM (c2))
return Qt;
- if (NILP (BVAR (current_buffer, case_fold_search)))
+ if (NILP (Vcase_fold_search))
return Qnil;
i1 = XFIXNAT (c1);
diff --git a/src/minibuf.c b/src/minibuf.c
index 58adde1bf66..0d5b375e450 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -2320,7 +2320,6 @@ syms_of_minibuf (void)
DEFSYM (Qcurrent_input_method, "current-input-method");
DEFSYM (Qactivate_input_method, "activate-input-method");
- DEFSYM (Qcase_fold_search, "case-fold-search");
DEFSYM (Qmetadata, "metadata");
DEFSYM (Qcycle_sort_function, "cycle-sort-function");
diff --git a/src/search.c b/src/search.c
index 2996d32fca1..75a67ff3223 100644
--- a/src/search.c
+++ b/src/search.c
@@ -281,7 +281,7 @@ looking_at_1 (Lisp_Object string, bool posix, bool
modify_data)
struct regexp_cache *cache_entry = compile_pattern (
string,
modify_match_data ? &search_regs : NULL,
- (!NILP (BVAR (current_buffer, case_fold_search))
+ (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_canon_table) : Qnil),
posix,
!NILP (BVAR (current_buffer, enable_multibyte_characters)));
@@ -402,7 +402,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string,
Lisp_Object start,
struct regexp_cache *cache_entry
= compile_pattern (regexp,
modify_match_data ? &search_regs : NULL,
- (!NILP (BVAR (current_buffer, case_fold_search))
+ (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_canon_table)
: Qnil),
posix,
@@ -1068,10 +1068,10 @@ search_command (Lisp_Object string, Lisp_Object bound,
Lisp_Object noerror,
BVAR (current_buffer, case_eqv_table));
np = search_buffer (string, PT, PT_BYTE, lim, lim_byte, n, RE,
- (!NILP (BVAR (current_buffer, case_fold_search))
+ (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_canon_table)
: Qnil),
- (!NILP (BVAR (current_buffer, case_fold_search))
+ (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_eqv_table)
: Qnil),
posix);
@@ -3402,7 +3402,7 @@ DEFUN ("re--describe-compiled", Fre__describe_compiled,
Sre__describe_compiled,
{
struct regexp_cache *cache_entry
= compile_pattern (regexp, NULL,
- (!NILP (BVAR (current_buffer, case_fold_search))
+ (!NILP (Vcase_fold_search)
? BVAR (current_buffer, case_canon_table) : Qnil),
false,
!NILP (BVAR (current_buffer,
--
2.42.0
profile-w-case-fold-search-patch
Description: Binary data
profile-without-case-fold-search-patch
Description: Binary data
--
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>
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, (continued)
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/13
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/14
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers,
Ihor Radchenko <=
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/15
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Stefan Monnier, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Eli Zaretskii, 2023/12/17
- bug#66117: 30.0.50; `find-buffer-visiting' is slow when opening large number of buffers, Ihor Radchenko, 2023/12/17