unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Kangas <stefan@marxist.se>
To: Sheng Yang <styang@fastmail.com>
Cc: Stephen Berman <stephen.berman@gmx.net>,
	Juri Linkov <juri@linkov.net>,
	Stefan Monnier <monnier@iro.umontreal.ca>,
	45379@debbugs.gnu.org
Subject: bug#45379: 28.0.50; Degraded Performance of describe-buffer-bindings
Date: Fri, 5 Mar 2021 20:44:33 -0800	[thread overview]
Message-ID: <CADwFkmkgYWQOzDP7WaYeyS5pS3ZA7iY4Fs-1F2Gymtata7A8nw@mail.gmail.com> (raw)
In-Reply-To: <CADwFkmn=GnQRNYbiA=zV8F1kPY+B5qHz4QhzvgkQMOia_x77Yw@mail.gmail.com> (Stefan Kangas's message of "Fri, 8 Jan 2021 11:08:14 -0600")

[-- Attachment #1: Type: text/plain, Size: 1168 bytes --]

tags 45379 + patch
thanks

Stefan Kangas <stefan@marxist.se> writes:

> "Sheng Yang" <styang@fastmail.com> writes:
>
>> Hi Juri,
>>
>> I recently came across a regression of performance in Emacs for
>> describe bindings, which I have reported as bug#45379. After
>> bisection, the offending seems to be a commit a649034336 you pushed in
>> November 2020, to fix bug#5423. [...]
>>
>> a649034336 * bad Don't show key ranges if shadowed by different commands
>
> BTW, the offending commit is not Juri's.  It is mine:
>
>     Author: Stefan Kangas <stefan@marxist.se>
>     Date:   Fri Nov 13 15:28:29 2020 +0100
>
>         Don't show key ranges if shadowed by different commands

Please try the attached patch and see that it fixes this performance
regression.

It turns out that we were doing unnecessary looping due to the above
mentioned commit.  While working on this, I also found that we can get
rid of an unnecessary call to char_table_ref_and_range, which should
make this function run even faster.

I'm also copying in Kenichi Handa, who was the last to touch this code.
Handa-san, please let us know if you have any comments on this patch.
Thanks in advance.

[-- Attachment #2: 0001-Fix-describe-buffer-bindings-performance-regression.patch --]
[-- Type: text/x-diff, Size: 3876 bytes --]

From f95c75f1112c1aae0bd06a6753b60ce8a591d6e2 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefan@marxist.se>
Date: Sat, 6 Mar 2021 05:32:32 +0100
Subject: [PATCH] Fix describe-buffer-bindings performance regression

* src/keymap.c (describe_vector): Improve char-table performance by
removing an unnecessary loop.  (Bug#45379)
(syms_of_keymap) <Qself_insert_command>: New DEFSYM.
---
 src/keymap.c | 47 +++++++++++++++++++----------------------------
 1 file changed, 19 insertions(+), 28 deletions(-)

diff --git a/src/keymap.c b/src/keymap.c
index 782931fadf..c70df98a6e 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2920,7 +2920,7 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
   Lisp_Object suppress = Qnil;
   bool first = true;
   /* Range of elements to be handled.  */
-  int from, to, stop;
+  int to, stop;
 
   if (!keymap_p)
     {
@@ -2940,32 +2940,33 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
   if (partial)
     suppress = intern ("suppress-keymap");
 
-  from = 0;
+  /* If VECTOR is a char-table, we had better put a boundary
+     between normal characters (-#x3FFF7F) and 8-bit characters
+     (#x3FFF80-).  */
   if (CHAR_TABLE_P (vector))
     stop = MAX_5_BYTE_CHAR + 1, to = MAX_CHAR + 1;
   else
     stop = to = ASIZE (vector);
 
-  for (int i = from; ; i++)
+  for (int i = 0; i < to; i++)
     {
       bool this_shadowed = false;
       Lisp_Object shadowed_by = Qnil;
-      int range_beg, range_end;
+      int range_beg;
       Lisp_Object val, tem2;
 
       maybe_quit ();
 
-      if (i == stop)
-	{
-	  if (i == to)
-	    break;
-	  stop = to;
-	}
-
       int starting_i = i;
 
       if (CHAR_TABLE_P (vector))
 	{
+	  /* Take care of the boundary.  */
+	  if (i == stop)
+	    stop = to;
+
+	  /* Find the first element between i and stop - 1.  Put its
+	     index in i.  */
 	  range_beg = i;
 	  i = stop - 1;
 	  val = char_table_ref_and_range (vector, range_beg, &range_beg, &i);
@@ -3024,21 +3025,8 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
       insert1 (Fkey_description (kludge, prefix));
 
       /* Find all consecutive characters or rows that have the same
-	 definition.  But, if VECTOR is a char-table, we had better
-	 put a boundary between normal characters (-#x3FFF7F) and
-	 8-bit characters (#x3FFF80-).  */
-      if (CHAR_TABLE_P (vector))
-	{
-	  while (i + 1 < stop
-		 && (range_beg = i + 1, range_end = stop - 1,
-		   val = char_table_ref_and_range (vector, range_beg,
-						   &range_beg, &range_end),
-		   tem2 = get_keyelt (val, 0),
-		   !NILP (tem2))
-		 && !NILP (Fequal (tem2, definition)))
-	    i = range_end;
-	}
-      else
+	 definition.  */
+      if (!CHAR_TABLE_P (vector))
 	while (i + 1 < stop
 	       && (tem2 = get_keyelt (AREF (vector, i + 1), 0),
 		   !NILP (tem2))
@@ -3047,10 +3035,12 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
 
       /* Make sure found consecutive keys are either not shadowed or,
 	 if they are, that they are shadowed by the same command.  */
-      if (CHAR_TABLE_P (vector) && i != starting_i)
+      if (CHAR_TABLE_P (vector) && i != starting_i
+	  /* Ignore `self-insert-command' for performance.  */
+	  && !EQ (definition, Qself_insert_command))
 	{
 	  Lisp_Object key = make_nil_vector (1);
-	  for (int j = starting_i + 1; j <= i; j++)
+	  for (int j = range_beg + 1; j <= i; j++)
 	    {
 	      ASET (key, 0, make_fixnum (j));
 	      Lisp_Object tem = shadow_lookup (shadow, key, Qt, 0);
@@ -3109,6 +3099,7 @@ syms_of_keymap (void)
   DEFSYM (Qdescribe_map_tree, "describe-map-tree");
 
   DEFSYM (Qkeymap_canonicalize, "keymap-canonicalize");
+  DEFSYM (Qself_insert_command, "self-insert-command");
 
   /* Now we are ready to set up this property, so we can
      create char tables.  */
-- 
2.30.1


  parent reply	other threads:[~2021-03-06  4:44 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-23  6:01 bug#45379: 28.0.50; Degraded Performance of describe-buffer-bindings styang
2021-01-08 16:47 ` Sheng Yang
2021-01-08 17:00   ` Stefan Kangas
2021-01-08 17:08   ` Stefan Kangas
2021-02-04 15:43     ` Sheng Yang
2021-03-06  4:44     ` Stefan Kangas [this message]
2021-03-06  8:15       ` Eli Zaretskii
2021-03-07  1:42         ` handa
2021-03-07  6:15           ` Eli Zaretskii
2021-03-30  7:01             ` Eli Zaretskii
2021-04-01 15:06               ` handa
2021-04-14  3:06                 ` Sheng Yang
2021-03-07  8:12         ` Stefan Kangas
2021-03-07  8:38           ` Eli Zaretskii
2021-05-04 23:31       ` Stefan Kangas
2021-05-06 10:11         ` Eli Zaretskii
2021-05-13 10:10         ` Eli Zaretskii
2021-06-26 21:51           ` Sheng Yang
2021-06-27  5:56             ` Eli Zaretskii
2021-09-07 18:53           ` Eli Zaretskii
2021-09-18 10:37             ` Eli Zaretskii
2021-09-18 12:34               ` Stefan Kangas
2021-09-18 13:24                 ` Eli Zaretskii
2021-09-18 14:39                   ` Stefan Kangas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CADwFkmkgYWQOzDP7WaYeyS5pS3ZA7iY4Fs-1F2Gymtata7A8nw@mail.gmail.com \
    --to=stefan@marxist.se \
    --cc=45379@debbugs.gnu.org \
    --cc=juri@linkov.net \
    --cc=monnier@iro.umontreal.ca \
    --cc=stephen.berman@gmx.net \
    --cc=styang@fastmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).