From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Anders Lindgren Newsgroups: gmane.emacs.bugs Subject: bug#16129: 24.3.50; Emacs slow with follow-mode when buffer ends before last window Date: Fri, 10 Jan 2014 19:52:18 +0100 Message-ID: References: <83bnzpu622.fsf@gnu.org> <8338l1t6ip.fsf@gnu.org> <83vbxsb2t6.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=047d7bb70b2eaab50a04efa239bc X-Trace: ger.gmane.org 1389379990 7893 80.91.229.3 (10 Jan 2014 18:53:10 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 10 Jan 2014 18:53:10 +0000 (UTC) Cc: 16129@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Jan 10 19:53:16 2014 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1W1hCl-0004D6-44 for geb-bug-gnu-emacs@m.gmane.org; Fri, 10 Jan 2014 19:53:15 +0100 Original-Received: from localhost ([::1]:58407 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1hCk-0004rt-JA for geb-bug-gnu-emacs@m.gmane.org; Fri, 10 Jan 2014 13:53:14 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44433) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1hCd-0004rj-Dt for bug-gnu-emacs@gnu.org; Fri, 10 Jan 2014 13:53:12 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W1hCY-00042C-G6 for bug-gnu-emacs@gnu.org; Fri, 10 Jan 2014 13:53:07 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:59729) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1hCY-000428-Bm for bug-gnu-emacs@gnu.org; Fri, 10 Jan 2014 13:53:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1W1hCX-0002fn-NK for bug-gnu-emacs@gnu.org; Fri, 10 Jan 2014 13:53:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Anders Lindgren Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 10 Jan 2014 18:53:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 16129 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 16129-submit@debbugs.gnu.org id=B16129.138937994910216 (code B ref 16129); Fri, 10 Jan 2014 18:53:01 +0000 Original-Received: (at 16129) by debbugs.gnu.org; 10 Jan 2014 18:52:29 +0000 Original-Received: from localhost ([127.0.0.1]:45513 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1W1hBx-0002eV-ES for submit@debbugs.gnu.org; Fri, 10 Jan 2014 13:52:29 -0500 Original-Received: from mail-wi0-f174.google.com ([209.85.212.174]:42879) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1W1hBr-0002eD-KF for 16129@debbugs.gnu.org; Fri, 10 Jan 2014 13:52:23 -0500 Original-Received: by mail-wi0-f174.google.com with SMTP id z2so8739061wiv.7 for <16129@debbugs.gnu.org>; Fri, 10 Jan 2014 10:52:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=XnYwPrw9TqL4vXfUmgsWTCJw+bJA23M83wCVemhwJrI=; b=Rbi5KaUVTlEJ18ApK5t0PMrrhog7mP6Cm7E46pyIA4B8tSVu84l4P66j5BNiI0T3FK mo2g2d3dgMJQ/quJh5uZofcJyUCUsoLojfBpUjf7eMpc4kBF9Wnw+zReHcu2lSsjGPzs sDfpadQpd3LzYDMjpg99CgRnp3zl8WvNBFxuGU3+DWaqsd5Q3uuvd98+UQcLs0h/ztjM 30ebB4CtBMZYKyofhd66QVaH6m3YRaXZrcdZq/HH99rzwDvHS/VJtHK1GvsZ9NCgXcPh TMwla83VsN0lHdnWQhF1Ij+5r0UqfhtETeLT5Hm+CR0d6R6eeqfsd/8TnmRQ+FdNoWlQ zSGg== X-Received: by 10.194.192.233 with SMTP id hj9mr10189008wjc.78.1389379938070; Fri, 10 Jan 2014 10:52:18 -0800 (PST) Original-Received: by 10.216.223.140 with HTTP; Fri, 10 Jan 2014 10:52:18 -0800 (PST) In-Reply-To: <83vbxsb2t6.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:83240 Archived-At: --047d7bb70b2eaab50a04efa239bc Content-Type: text/plain; charset=ISO-8859-1 Eli, I agree that follow-mode slows down Emacs, even though the effect is more visible now compared to earlier. Up to Emacs 22, it really was fast. With Emacs 23 it feels like there is a definitive slowdown, which is visible e.g. when typing plain text fast and when scrolling window. (In fact, at work where I use Windows, I still use Emacs 22.) Implementing follow-mode in the display engine sounds like a wonderful idea! In fact, when I originally wrote it (back in 1995) I intended it to be a prototype, but I envisioned the real implementation to be done in the display engine. Unfortunately, the people responsible for the display engine at the time didn't like the idea, so I made follow-mode to an all-lisp package. Concretely, how do we proceed from here? I don't have the necessary knowledge of the internals of the display engine and I don't have much time to spend on a major rewrite like this. However, if someone decides to proceed with this, I will try to support them as much that I can. -- Anders On Fri, Jan 10, 2014 at 10:31 AM, Eli Zaretskii wrote: > > Date: Tue, 7 Jan 2014 09:13:19 +0100 > > From: Anders Lindgren > > Cc: Stefan Monnier , > 16129-done@debbugs.gnu.org > > > > Thanks, I tried it out on the trunk, and it seems to be working > correctly! > > Thanks for testing. > > > I'm open to reimplementing follow-mode in another way, if you think that > > it's necessary. However, there are two different uses of > set-window-start, > > and maybe we don't need to change both: > > > > * Normally, when the position of the active window change, the start of > the > > other windows are updated. This occurs very infrequent, and it would > > require a redisplay anyway. > > * When a window shows the empty tail of a buffer, point-max is "hammered" > > into window-start to ensure that the display engine doesn't recenter the > > window. > > > > Of the two uses, I only consider the second a problem. > > I think we should consider both, because they both are detrimental to > the efficiency of redisplay. > > You see, the Emacs redisplay has a very complex problem to solve, > because there are a gazillion of ways to change some obscure Lisp data > structure that can potentially change what should be on the glass. > However, if redisplay needed to examine all those potential changes > and decide whether they actually change the displayed portion of the > buffer, redisplay would become painfully slow. > > So we have a lot of optimizations in the display engine, each of which > basically says: if none of the following events happened since last > redisplay cycle, then this and that potential changes don't need to be > considered. Each optimization comes with a list of events that > invalidate it. Redisplay basically tries to apply each optimization > in sequence, starting from the most aggressive one, until it finds one > that can be applied, or falls back to the unoptimized code, which > redisplays the entire window. > > To be able to pull this trick, the display engine maintains a set of > flags, each one of which tells whether a particular kind of event > happened since last redisplay. These flags are consulted when the > display engine must decide which optimization, if any, is applicable. > > One of these flag variables is the window start point: as long as it > stays put, Emacs does not need to bother recomputing it, and does not > need to invalidate the information it keeps about where in the buffer > text is the window start point, given the current value of point. > > When a post-command-hook forces a value of window-start, some of these > optimizations are inapplicable, so Emacs responsiveness suffers. For > example, when follow-mode is on, Emacs frequently needs to redisplay > the same window twice in a row, instead of just once. > > > However, it would probably be easy to handle if there would be a > > windows-specific option or call-back that could control if the > > window should be recentered or not. > > That's not what I had in mind. Instead, we could have special code in > the display engine that would automatically scroll the other window(s) > when follow-mode says they should. IOW, when Emacs redisplays some > window because something changed in it, the display engine could > decide right there and then that some other windows need to be > redisplayed, and moreover, compute their window-start point > automatically or by calling some Lisp. After all, the relations that > determine the window-start of the windows which participate in > follow-mode is quite simple: the next window should begin where the > previous one ends. All of this could be done in a single redisplay > cycle, thereby avoiding the need for a post-command-hook in the first > place. The benefit would be not only a more efficient redisplay, but > also faster Emacs, because many commands do not affect any display, > and many others do not affect windows that are under follow-mode, so > in this case a post-command-hook forces Emacs to perform unnecessary > redisplay. > > > While I'm at it, I realized today that the responsiveness when using > > follow-mode was better when running the cursor up and down compared to > left > > and right. When looking into the details I saw that the arrow keys no > > longer were bound to previous- and next-char, so we need to apply the > patch > > below to follow-mode (I don't have write-access to the archives). > > I installed this in your name. Thanks. > --047d7bb70b2eaab50a04efa239bc Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Eli,

I agree that follow-mode slows dow= n Emacs, even though the effect is more visible now compared to earlier. Up= to Emacs 22, it really was fast. With Emacs 23 it feels like there is a de= finitive slowdown, which is visible e.g. when typing plain text fast and wh= en scrolling window. (In fact, at work where I use Windows, I still use Ema= cs 22.)

Implementing follow-mode in the display engine sounds l= ike a wonderful idea! In fact, when I originally wrote it (back in 1995) I = intended it to be a prototype, but I envisioned the real implementation to = be done in the display engine. Unfortunately, the people responsible for th= e display engine at the time didn't like the idea, so I made follow-mod= e to an all-lisp package.

Concretely, how do we proceed from here? I don't ha= ve the necessary knowledge of the internals of the display engine and I don= 't have much time to spend on a major rewrite like this. However, if so= meone decides to proceed with this, I will try to support them as much that= I can.

=A0 =A0 -- Anders


On Fri, Jan 10, 2014 at 10:31 AM, Eli Z= aretskii <eliz@gnu.org> wrote:
> Date: Tue, 7 Jan 2014 09:13:19 +0100 > From: Anders Lindgren <andlind= @gmail.com>
> Cc: Stefan Monnier <mon= nier@iro.umontreal.ca>, 16129-done@debbugs.gnu.org
>
> Thanks, I tried it out on the trunk, and it seems to be working correc= tly!

Thanks for testing.

> I'm open to reimplementing follow-mode in another way, if you thin= k that
> it's necessary. However, there are two different uses of set-windo= w-start,
> and maybe we don't need to change both:
>
> * Normally, when the position of the active window change, the start o= f the
> other windows are updated. This occurs very infrequent, and it would > require a redisplay anyway.
> * When a window shows the empty tail of a buffer, point-max is "h= ammered"
> into window-start to ensure that the display engine doesn't recent= er the
> window.
>
> Of the two uses, I only consider the second a problem.

I think we should consider both, because they both are detrimental to=
the efficiency of redisplay.

You see, the Emacs redisplay has a very complex problem to solve,
because there are a gazillion of ways to change some obscure Lisp data
structure that can potentially change what should be on the glass.
However, if redisplay needed to examine all those potential changes
and decide whether they actually change the displayed portion of the
buffer, redisplay would become painfully slow.

So we have a lot of optimizations in the display engine, each of which
basically says: if none of the following events happened since last
redisplay cycle, then this and that potential changes don't need to be<= br> considered. =A0Each optimization comes with a list of events that
invalidate it. =A0Redisplay basically tries to apply each optimization
in sequence, starting from the most aggressive one, until it finds one
that can be applied, or falls back to the unoptimized code, which
redisplays the entire window.

To be able to pull this trick, the display engine maintains a set of
flags, each one of which tells whether a particular kind of event
happened since last redisplay. =A0These flags are consulted when the
display engine must decide which optimization, if any, is applicable.

One of these flag variables is the window start point: as long as it
stays put, Emacs does not need to bother recomputing it, and does not
need to invalidate the information it keeps about where in the buffer
text is the window start point, given the current value of point.

When a post-command-hook forces a value of window-start, some of these
optimizations are inapplicable, so Emacs responsiveness suffers. =A0For
example, when follow-mode is on, Emacs frequently needs to redisplay
the same window twice in a row, instead of just once.

> However, it would probably be easy to handle if there would be a
> windows-specific option or call-back that could control if the
> window should be recentered or not.

That's not what I had in mind. =A0Instead, we could have special = code in
the display engine that would automatically scroll the other window(s)
when follow-mode says they should. =A0IOW, when Emacs redisplays some
window because something changed in it, the display engine could
decide right there and then that some other windows need to be
redisplayed, and moreover, compute their window-start point
automatically or by calling some Lisp. =A0After all, the relations that
determine the window-start of the windows which participate in
follow-mode is quite simple: the next window should begin where the
previous one ends. =A0All of this could be done in a single redisplay
cycle, thereby avoiding the need for a post-command-hook in the first
place. =A0The benefit would be not only a more efficient redisplay, but
also faster Emacs, because many commands do not affect any display,
and many others do not affect windows that are under follow-mode, so
in this case a post-command-hook forces Emacs to perform unnecessary
redisplay.

> While I'm at it, I realized today that the responsiveness when usi= ng
> follow-mode was better when running the cursor up and down compared to= left
> and right. When looking into the details I saw that the arrow keys no<= br> > longer were bound to previous- and next-char, so we need to apply the = patch
> below to follow-mode (I don't have write-access to the archives).<= br>
I installed this in your name. =A0Thanks.

--047d7bb70b2eaab50a04efa239bc--