all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: JD Smith <jdtsmith@gmail.com>
Cc: emacs-devel@gnu.org, casouri@gmail.com
Subject: Re: Mitigating the long-lines penalty in vundo
Date: Sun, 17 Dec 2023 20:07:47 +0200	[thread overview]
Message-ID: <83a5q8k8i4.fsf@gnu.org> (raw)
In-Reply-To: <186F0A42-25E1-4A12-B6A1-F5B0F1465447@gmail.com> (message from JD Smith on Sun, 17 Dec 2023 12:49:27 -0500)

> From: JD Smith <jdtsmith@gmail.com>
> Date: Sun, 17 Dec 2023 12:49:27 -0500
> Cc: emacs-devel@gnu.org,
>  casouri@gmail.com
> 
> That said, with long lines (>10-20K columns, say) visible, the problem remains that overall Emacs is
> mildly but noticeably less responsive, in the mini-buffer, in other buffers, etc., until the vundo buffer is
> hidden.  Perhaps that’s just the minimum penalty paid for such long lines.

Long lines with faces and overlays, I should say.

>  The current-column docs do say:
> 
>  In a buffer with very long lines, the value will be an approximation,
>  because calculating the exact number is very expensive.
> 
>  The "very long lines" case happens when the line's length exceeds the
>  long-line-threshold, which in your case it most probably doesn't
>  (unless you lower long-line-threshold considerably).  So this part of
>  the doc string is not relevant to your problem.
> 
> I was only referring to the “very expensive” part. 

The "very expensive" part is also only when lines are around
long-line-threshold.  Again, not your case.

>  Yes. The problem is that vundo.el uses 'display' properties _a_lot_,
>  and those slow down current-column, because each time it sees a
>  'display' property whose value is a string, it needs to extract the
>  property value and calculate the width of that string, to account for
>  its width on display.
> 
> That would have indeed been a good explanation for the additional slowness, but in fact vundo does
> not use 'display properties:

I do see 'display' properties being used:

  (defun vundo--highlight-node (node)
    "Highlight NODE as current node."
    (unless vundo--highlight-overlay
      (setq vundo--highlight-overlay
	    (make-overlay (1- (vundo-m-point node)) (vundo-m-point node)))
      (overlay-put vundo--highlight-overlay
		   'display (vundo--translate "●"))
      (overlay-put vundo--highlight-overlay
		   'face 'vundo-highlight)
      ;; Make current node’s highlight override last saved node’s
      ;; highlight, should they collide.
      (overlay-put vundo--highlight-overlay 'priority 2))
    (move-overlay vundo--highlight-overlay
		  (1- (vundo-m-point node))
		  (vundo-m-point node)))

> Indeed this was a vundo problem in that there was no need to call current-column over and over for
> each node.  But the basic slowness of current-column remains, so unless there are low-hanging
> improvements to be made there, algorithms that need frequent column calculations would need to try
> other approaches.

Lisp programs are not supposed to need frequent column calculations,
certainly not several times on the same line.

> * Current column is reasonably fast counting long lines of plain text — 175ms total to compute each
>  column at 6000 nodes spread over 18K columns.
> * current-column is quite slow counting unicode characters: about 21x slower than the ascii
>  equivalents.  Perhaps this is because unicode chars can have non-standard widths, so emacs
>  needs to do some additional checks?

No.  I can understand why non-ASCII characters are somewhat slower,
since each one of them is several bytes, not just one, and we convert
the multibyte representation into a codepoint on the fly.  But 21-fold
slowdown sounds excessive.

> * But this isn’t the full story, because current-column is also (separately) quite slow counting plain
>  characters with attached faces: 33x slower than the fast case. This one seems less intuitive to me.
>  Can faces also (in principle) alter the character width (like italic for example)?

When buffer text has faces (or any other text properties, really)
current-column uses a slower algorithm, because the faster one will
yield incorrect results.

> * Combining these two (unicode chars with alternating faces) is the worst case — 43x slower than
>  the fast case of unadorned plain chars.  This was vundo’s case.

Then vundo is better redesigned to avoid such massive reliance on
current-column.

There's one more factor to consider here: current-column always starts
from the beginning of the line.  If vundo needs to call current-column
many times on the same line, it loses because it each time starts from
BOL, in effect throwing away the results of the previous calculation.
This wastes CPU cycles.  It might be better to use sum char-width
values of individual characters instead.



  reply	other threads:[~2023-12-17 18:07 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-16 16:19 Mitigating the long-lines penalty in vundo JD Smith
2023-12-16 16:45 ` Eli Zaretskii
2023-12-16 18:54   ` JD Smith
2023-12-16 19:13     ` Eli Zaretskii
2023-12-16 20:32       ` Stephen Berman
2023-12-16 22:00       ` JD Smith
2023-12-17  7:28         ` Eli Zaretskii
2023-12-17 17:49           ` JD Smith
2023-12-17 18:07             ` Eli Zaretskii [this message]
2023-12-17 19:26               ` JD Smith
2023-12-17 19:43                 ` Eli Zaretskii

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

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

  git send-email \
    --in-reply-to=83a5q8k8i4.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=casouri@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=jdtsmith@gmail.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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.