Subject: Re: bug#56682: Fix the long lines font locking related slowdowns

From: Eli Zaretskii <[email-masked]>
Date: Tue, 26 Jul 2022 20:46:24 +0300

> Cc: [email-masked], [email-masked], [email-masked]
> Date: Tue, 26 Jul 2022 15:41:49 +0300
> From: Eli Zaretskii <[email-masked]>
> 
> > I just tried again, and on my machine with an optimized build C-s </ RET 
> > takes 220 seconds to finish (and cannot be interrupted).  That's what I 
> > call "hang".  With 350e97d78e, C-s </ RET takes about 1 second.  That's 
> > what I call "slow" (without truncate-lines C-s </ RET is instantaneous).
> 
> OK, I will take a look soon.  That change makes us use a branch of
> code that AFAIU was never used since it was written, so some kind of
> trouble can be expected.

Heh, it's a case of "better is worse".  There's nothing wrong with the
change in commit 350e97d78e: it does indeed make redisplay of
long-and-truncated lines significantly faster.  And that speedup is
what's causing the problem: because the initial redisplay of the
buffer, before the results of C-s are displayed, is much faster, the
lazy-highlighting starts very soon, and it inserts thousands of
overlays into the buffer (because it by default highlights all the
matches till window-end, which is EOB in this case).  And once it
inserts enough overlays, we are dead in the water: the shortcut in
forward_to_next_line_start can no longer be taken, and we instead
iterate the slow way, one character at a time, all the way to EOB, and
on top of that need on the way to examine every one of the overlays
inserted by lazy-highlighting.

If I revert commit 350e97d78e, redisplay of long-and-truncated lines
becomes much slower, but because of that, lazy-highlighting doesn't
have time to highlight anything before you hit C-s for repeated
search, and thus there are no overlays in the buffer, and on the
average the responses are faster.

I tried to limit the lazy-highlighting by long-line-threshold, but the
speedup due to that is not significant enough (because even a single
overlay in the long line disables the shortcut in
forward_to_next_line_start).  Only limiting
lazy-highlight-initial-delay to, say, 1 sec and
lazy-highlight-max-at-a-time to a small number (like 2 or 5) makes the
problem go away because lazy-highlighting doesn't have enough time to
highlight too much.  And even then once you go deep enough into the
file, the problem comes back.

At this point, I think the only way to produce reasonable performance
from C-s in this case is to turn off lazy-highlighting when lines are
truncated and the buffer has long lines.  Which means we need to
expose the value of long_line_optimizations_p to Lisp, via an accessor
function.  I already have one other use for this: "C-x =", which
attempts to report the column of the character, something that is very
slow in a long-and-truncated line.  And I think we will see more cases
where Lisp code needs to know about this in order to adapt itself to
long lines.

Comments?