bug#81623: 32.0.50; Long-line optimization severely slows redisplay of invisible newlines
Scott Guest <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
Run the following under `emacs -Q -l`:
```elisp
(defun reproduce (long-line-length)
(let ((buffer (generate-new-buffer " *redisplay bug*")) body-begin start)
(with-current-buffer buffer
;; This line is before, and outside, the invisible region below.
(insert (make-string long-line-length ?x) "\n")
;; U+03BB makes byte and character positions differ.
(insert (string #x03bb) " visible header\n")
(setq body-begin (point))
;; START will be inside a logical line, after 40,000 hidden newlines.
(insert (make-string 40000 ?\n) "x")
(setq start (point))
(insert "\n")
(put-text-property body-begin (point-max) 'invisible t))
(switch-to-buffer buffer)
(goto-char start)
(set-window-start nil start t)
(force-window-update)
(let ((time (current-time)))
(redisplay t)
(princ (format "long line %d; optimization %S; redisplay %.3fs\n"
long-line-length (long-line-optimizations-p)
(float-time (time-since time)))
#'external-debugging-output))))
(reproduce 49999)
(reproduce 50000)
(kill-emacs)
```
Typical output:
```text
long line 49999; optimization nil; redisplay 0.126s
long line 50000; optimization t; redisplay 2.101s
```
Crossing the default `long-line-threshold` by one character makes
redisplay approximately 17 times slower in this run. With larger inputs
where I've encountered this in the wild, the slowdown is egregious
enough that it's indistinguishable from a hang.
Tested with GNU Emacs 32.0.50 from master, commit
`7861c306427e7488a623d296e1efb05509cc7cc6`, in a graphical session.