Subject: bug#62780: 30.0.50; Redisplay gets slow when using Org tables + show-trailing-whitespace

From: Eli Zaretskii <[email-masked]>
Date: Wed, 12 Apr 2023 10:19:38 +0300

> From: Ihor Radchenko <[email-masked]>
> Cc: [email-masked]
> Date: Tue, 11 Apr 2023 19:41:01 +0000
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > show-trailing-whitespace disables quite a few redisplay optimizations,
> > including even the cursor-motion optimization (when nothing has
> > changed on display except the position of point).  And full thorough
> > redisplay becomes slow when you have relatively long lines, because
> > Emacs is forced to consider all of them.
> 
> Well. But it is not even that big of a file.

The size of the file doesn't matter, only what's shown in the window
matters.

> And the lines are shorter than window width.

Not here, they aren't: a 50x30 table takes more than twice the default
window width of "emacs -Q".  However, I don't think this aspect is
important, either.

> > In addition, org-table seems to put a large number of 'display'
> > properties (like, 2 per cell?), which also slows down redisplay.
> 
> These properties are for the purpose of bidirectional ordering:
> 
> (defconst org-table--separator-space-pre
>   (propertize " " 'display '(space :relative-width 1))
>   "Space used in front of fields when aligning the table.
> This space serves as a segment separator for the purposes of the
> bidirectional reordering.
> Note that `org-table--separator-space-pre' is not `eq' to
> `org-table--separator-space-post'.  This is done to prevent Emacs from
> visually merging spaces in an empty table cell.  See bug#45915.")

I understand.  But it's definitely what causes most of the slowdown;
show-trailing-whitespace just adds the last straw.  With the patch
below I can see no slowdown at all with your recipe.

> Maybe there is a better way?

Maybe.  Can you point me to the discussion which caused you to use
these display properties there?  I think this was done in two steps:
first you added the same display property as pre and post, then made
them subtly different; I need to re-read the discussions that led to
both of these.

Alternatively, if you can describe the use cases where these
properties are needed, that could be enough for me to try to look for
alternative solutions.

> > Are you saying there's been a regression in Emacs 30 in this situation
> > wrt Emacs 29 and Emacs 28?  I don't think I see a regression in my
> > testing here.
> 
> No, I do not mean a regression. But the slowdown appears to be
> unreasonable for such a small test case. What is the point having
> `show-trailing-whitespace' if it is this much inefficient? Maybe a
> simple font-lock rule can be better?

See above: show-trailing-whitespace is not the main culprit here;
these particular display properties are.  If you could produce a perf
profile with this recipe, it might give ideas for speeding up the C
code without any changes on the Lisp level.

Btw, these properties were introduced into org-table.el some time ago,
so how come this issue comes up only now?  Aren't Org tables used
quite a lot?

diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el
index 5116b11..658b5aa 100644
--- a/lisp/org/org-table.el
+++ b/lisp/org/org-table.el
@@ -4354,11 +4354,12 @@ org-table--align-field
 		   ("r" (make-string spaces ?\s))
 		   ("c" (make-string (/ spaces 2) ?\s))))
 	 (suffix (make-string (- spaces (length prefix)) ?\s)))
-    (concat org-table--separator-space-pre
+    (concat " " ;org-table--separator-space-pre
 	    prefix
 	    field
 	    suffix
-	    org-table--separator-space-post)))
+	    " " ;org-table--separator-space-post
+            )))
 
 (defun org-table-align ()
   "Align the table at point by aligning all vertical bars."