Package: emacs;
Reported by: JD Smith <jdtsmith <at> gmail.com>
Date: Wed, 11 Jun 2025 23:09:02 UTC
Severity: normal
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Message #23 received at 78766 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: JD Smith <jdtsmith <at> gmail.com> Cc: 78766 <at> debbugs.gnu.org Subject: Re: bug#78766: 100-4000x redisplay slowdown with vscroll>0 and make-cursor-line-fully-visible=t Date: Sat, 14 Jun 2025 09:59:09 +0300
> From: JD Smith <jdtsmith <at> gmail.com> > Date: Fri, 13 Jun 2025 14:04:03 -0400 > Cc: 78766 <at> debbugs.gnu.org > > > > > On Jun 13, 2025, at 11:16 AM, Eli Zaretskii <eliz <at> gnu.org> wrote: > > > >> From: JD Smith <jdtsmith <at> gmail.com> > >> Date: Fri, 13 Jun 2025 10:07:05 -0400 > >> > >> Quick followup. I was able to instrument the single function `set_iterator_to_next' to track total call count and distribution of call times of this core function. Since the instrumentation slowed the test down so much, I profiled moving (forward-char) by just 3 chars with redisplay in a partially visible top line, using the slow setting of make-cursor-line-fully-visible=t. > >> > >> The total call count per character moved in the slow case is enormous: >800K. > > > > Thanks, but this doesn't really add any useful info. > > It shows that the iterator movement is not in and of itself slow, but that it is called many times per character movement, which was your request before. True, but it's hardly new information. Problems with slow redisplay happen not because set_iterator_to_next is slow, but because it is called too many times, for whatever reasons. It is those reasons that are interesting, because the way to make redisplay fast enough is to eliminate the reasons for those many calls. > > set_iterator_to_next is too low-level to explain what's going on. It > > is expected that it will be called many times, but the question is > > why? > > I can see that, but on the other hand, it would be strange to expect it to be called 2850x as many times per character movement when a setting is toggled from nil to t. That seems to me quite excessive. Your intuitions here may be better. Which is why I'm asking why these many calls happen. What my intuition tells was described up-thread, but what we need here is facts: why does Emacs in fact try to redraw this window's characters so many times? > > And the answer to that is at higher levels, at the level of the > > functions called by redisplay_window. > > IOW, if we call set_iterator_to_next so many times, we either (a) > > redraw the entire window many times, or (b) redraw some small subset > > of the window's lines even more times. Which one(s) of these actually > > happen and why is the interesting question. > > I'm happy to perform call count and duration stats for other functions if you want to suggest some, but it sounds like you may be better positioned to quickly drill down on this. The way to answer these questions is to step through the code in redisplay_window and see what it does and why in that case. If there's no answer to this question by the time I get enough free time to do it myself, I will. > > And you still haven't explained to me what you want Emacs to do when > > you set vscroll > 0 (which necessarily makes the top-most screen line > > partially-visible) and ... make-cursor-line-fully-visible = t > > I'm agnostic. Expanding on what I said before, Emacs could either: > > 1. Prevent the cursor from landing on a partially visible top line. If it tries to go there, adjust window-start. This is AFAIU a new display feature that currently doesn't exist. If I'm right, it will need addition of new code. > 2. Keep the current behavior, allowing the cursor to fall on such a line, but eliminate the ~3000x slower path that must be lurking there. That's impossible, because make-cursor-line-fully-visible cannot be ignored under the current code. It's a hard requirement, and is very central to one of the most important goals of the design of the Emacs display engine: ensure that point is always (fully) visible in the window. > > These two contradict one another, so you basically ask Emacs to square the circle. > > I don't see the inconsistency. These two settings together do not imply a desire for the cursor to end up on the partially-visible line. The setting is not called "make-top-line-fully-visible". The way the display engine is designed, it first find a promising starting-point for displaying the buffer in its window, then tries to display the window with that start point, then check whether such a display is successful (and here it checks whether point is in a fully-visible screen line, among others). I hope you understand the conundrum now? > > You also haven't explained why using the solution of > > pixel-scroll-precision-mode is not good for your mode. > > As I mentioned earlier: > > > this leads to partially visible lines causing problems in various other situations (e.g. comint-scroll-show-maximum-output). So disabling isn't ideal. > > Disabling make-cursor-line-fully-visible leads to... unwanted partially visible cursor lines at the bottom of the window (presumably the reason it exists to begin with). > > It doesn't affect scrolling, so this slowness bug is AFAIU the only reason to disable it. My mode isn't central to this story, other than the fact that it revealed the problem. FWIW, I consider all these weak justifications when you are literally fighting against the design of the display engine. > Note that make-cursor-line-fully-visible = t is the default, and vscroll>0 can readily occur via line-move across tall images, no pixel-scrolling needed. From simple.el: > > ;; If we moved into a tall line, set vscroll to make > ;; scrolling through tall images more smooth. Yes, "for scrolling through tall images". That's what vscroll was designed for, but you are using it for completely different purposes. Why is it a surprise that it doesn't work well? More generally, when will authors of Lisp packages understand a simple truth that the Emacs design principles basically place hard limitations on what Lisp programs can usefully and efficiently do, and stop attempts to use the Emacs features way out of their design space? (No, don't answer that.)
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.