* Deffering redisplay in COMINT
@ 2012-12-07 1:08 Michael Mauger
2012-12-25 11:09 ` Vitalie Spinu
0 siblings, 1 reply; 9+ messages in thread
From: Michael Mauger @ 2012-12-07 1:08 UTC (permalink / raw)
To: Emacs Devel
I don't believe this is possible, but I figured I'd run it past the brain trust....
In sql-interactive-mode, a derivative of comint, I will submit a SELECT statement that returns many very long rows (2000+ characters per line). The redisplay fireworks that follow are impressive but slow. As text streams to the buffer with `auto-hscroll-mode' enabled the screen flashes as it redraws the buffer with more lines of data and scrolled horizontally in different places until all the data stream is complete.
I have figured out how to turn off horizontal scrolling with a `comint-preoutput-filter-function' and a `pre-command-hook' for the duration of SQL command so the redisplay is limited to a slow march straight down the page without the intervening horizontal scrolling but the column number in the mode line going crazy. I've also discovered that if I switch to another buffer so that the SQL buffer is not displayed and then switch back, the SQL buffer is populated very quickly. (That is, Emacs can fetch the results quickly, it just can't redraw it quickly a couple of hundred times)
So what I'm asking: Is there a way (say by setting `inhibit-redisplay' to t) for the duration of the comint command and then restoring redisplay when I am at the prompt at the end. The trick that I use for `auto-hscroll-mode' won't work because I don't find out about the completion until the user causes an event. I understand also that I don't want to universally block redisplay in case I switch to another buffer while the comint command is running and I want to interact with another buffer (i.e., I want to inhibit redisplay in that buffer only--buffer-local inhibit-redisplay). Looking at comint.el and based on my understanding of how processes are handled, I don't believe that it is easy to do because I don't know when the output is complete. (I've noticed in my disable auto-hscroll-mode code that the comint-preoutput-filter-function will get called a couple of hundred times with chunks of the output. I'm probably getting a redisplay after
each chunk.)
My only thought is that I could route the output to a temp buffer until I see the prompt at the end of a chunk (ala the comint redirection code, a very non-Emacs 20+ way of doing things), and then move the output to the original buffer. Essentially buffering the output until it's complete. Thoughts? Am I missing an obvious hook? (pre-command isn't it, it fires only on input, unless I can feed input to it to force it when done)
Am I SOL?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2012-12-07 1:08 Deffering redisplay in COMINT Michael Mauger
@ 2012-12-25 11:09 ` Vitalie Spinu
2013-01-06 8:09 ` Michael Mauger
0 siblings, 1 reply; 9+ messages in thread
From: Vitalie Spinu @ 2012-12-25 11:09 UTC (permalink / raw)
To: Michael Mauger; +Cc: Emacs Devel
>> Michael Mauger <mmaug@yahoo.com>
>> on Thu, 6 Dec 2012 17:08:33 -0800 (PST) wrote:
> I don't believe this is possible, but I figured I'd run it past the brain trust....
> In sql-interactive-mode, a derivative of comint, I will submit a SELECT
> statement that returns many very long rows (2000+ characters per line). The
> redisplay fireworks that follow are impressive but slow. As text streams to
> the buffer with `auto-hscroll-mode' enabled the screen flashes as it redraws the
> buffer with more lines of data and scrolled horizontally in different places
> until all the data stream is complete.
> I have figured out how to turn off horizontal scrolling with a
> comint-preoutput-filter-function' and a `pre-command-hook' for the duration of
> SQL command so the redisplay is limited to a slow march straight down the page
> without the intervening horizontal scrolling but the column number in the mode
> line going crazy. I've also discovered that if I switch to another buffer so
> that the SQL buffer is not displayed and then switch back, the SQL buffer is
> populated very quickly. (That is, Emacs can fetch the results quickly, it just
> can't redraw it quickly a couple of hundred times)
> So what I'm asking: Is there a way (say by setting `inhibit-redisplay' to t) for
> the duration of the comint command and then restoring redisplay when I am at the
> prompt at the end. The trick that I use for `auto-hscroll-mode' won't work
> because I don't find out about the completion until the user causes an event. I
> understand also that I don't want to universally block redisplay in case I
> switch to another buffer while the comint command is running and I want to
> interact with another buffer (i.e., I want to inhibit redisplay in that buffer
> only--buffer-local inhibit-redisplay). Looking at comint.el and based on my
> understanding of how processes are handled, I don't believe that it is easy to
> do because I don't know when the output is complete. (I've noticed in my
> disable auto-hscroll-mode code that the comint-preoutput-filter-function will
> get called a couple of hundred times with chunks of the output. I'm probably
> getting a redisplay after
> each chunk.)
> My only thought is that I could route the output to a temp buffer until I see
> the prompt at the end of a chunk
To the best of my knowledge this is the only way out. But it is not bad
at all. You have to replace comint-output-filter with your own filter
that does that. The filter is triggered each time emacs receives output
from the sub-process (roughly 500 chars last time I counted). It's
pretty trivial to wait for a prompt at the end of output chunk, and you
will be surprised how reliable this procedure actually is.
This is how we do it in ESS:
(defun ess-wait-for-process (proc &optional sec-prompt wait force-redisplay)
"Wait for 'busy property of the process to become nil.
If SEC-PROMPT is non-nil return if secondary prompt is detected
regardless of whether primary prompt was detected or not. If
WAIT is non-nil wait for WAIT seconds for process output before
the prompt check, default 0.001s. When FORCE-REDISPLAY is non-nil
force redisplay. You better use WAIT >= 0.1 if you need
FORCE-REDISPLAY to avoid excesive redisplay."
(unless (eq (process-status proc) 'run)
(ess-error "ESS process has died unexpectedly."))
(setq wait (or wait 0.001)) ;;xemacs is stuck if it's 0 here
(save-excursion
(while (or (accept-process-output proc wait)
(if (and sec-prompt (process-get proc 'sec-prompt))
nil
(if force-redisplay (redisplay 'force))
(process-get proc 'busy))))))
The 'busy is set in the process filter by searching for prompt anchored
at the end of output chunk.
HTH,
Vitalie
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2012-12-25 11:09 ` Vitalie Spinu
@ 2013-01-06 8:09 ` Michael Mauger
2013-01-08 18:19 ` Stefan Monnier
0 siblings, 1 reply; 9+ messages in thread
From: Michael Mauger @ 2013-01-06 8:09 UTC (permalink / raw)
To: Vitalie Spinu; +Cc: Emacs Devel
>________________________________
> Vitalie Spinu <spinuvit@gmail.com>
> on Tuesday, December 25, 2012 6:09 AM wrote:
>
> >> Michael Mauger <mmaug@yahoo.com>
> >> on Thu, 6 Dec 2012 17:08:33 -0800 (PST) wrote:
>
> > In sql-interactive-mode, a derivative of comint, I will submit a SELECT
> > statement that returns many very long rows (2000+ characters per line). The
> > redisplay fireworks that follow are impressive but slow. As text streams to
> > the buffer with `auto-hscroll-mode' enabled the screen flashes as it redraws the
> > buffer with more lines of data and scrolled horizontally in different places
> > until all the data stream is complete.
>
....
>
> > My only thought is that I could route the output to a temp buffer until I see
> > the prompt at the end of a chunk
>
>To the best of my knowledge this is the only way out. But it is not bad
>at all. You have to replace comint-output-filter with your own filter
>that does that. The filter is triggered each time emacs receives output
>from the sub-process (roughly 500 chars last time I counted). It's
>pretty trivial to wait for a prompt at the end of output chunk, and you
>will be surprised how reliable this procedure actually is.
>
>This is how we do it in ESS:
>
> (defun ess-wait-for-process (proc &optional sec-prompt wait force-redisplay)
....
>
>
Thanks for your input. I took a look, but that approach makes emacs
modal, in that it locks up until the output is complete. I want to still
have a responsive editor since it make take a while before results start
to appear. But I've come up with a solution that gets reasonable
performance and only has a minor functional impact.
I'll give a brief description here, and I'll release this as a SQL-related
add-in in the ELPA shortly.
It's set up as a minor mode so it can be disabled in case it causes
problems. When it's enabled, it activates a pre and post output hooks.
The pre hook only activates if the mode is enabled and truncate-lines
is set. When active, it disables auto-hscroll-mode. It then appends
the output text to a temporary buffer and then returns a window's
width worth of characters of each line in the temp buffer to
be written to the output buffer. The output appears to fill each
line without the display slowdown due to long displayed lines.
And because hscroll is turned off, the text merely flows up the
screen quickly.
When the post output hook is called and it detects when the last
output text matches the prompt regexp, then it iterates thru
the temporary buffer and the output buffer starting at
comint-last-input-end. It takes each line after the window-
width worth of characters from the temp buffer and inserts them
at the end of each line in the output buffer. Once the output
buffer has been filled in with all the off-window text it re-enables
the horizontal scrolling.
The result is fast smooth scrolling and an often unnoticeable
hesitation when it is complete. It's not vital to have this to
use sql-mode, but having it as an add-on minor mode eliminates
a significant distraction when doing query development in Emacs.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-06 8:09 ` Michael Mauger
@ 2013-01-08 18:19 ` Stefan Monnier
2013-01-11 14:40 ` Michael Mauger
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2013-01-08 18:19 UTC (permalink / raw)
To: Michael Mauger; +Cc: Vitalie Spinu, Emacs Devel
> The pre hook only activates if the mode is enabled and truncate-lines
> is set. When active, it disables auto-hscroll-mode. It then appends
> the output text to a temporary buffer and then returns a window's
> width worth of characters of each line in the temp buffer to
> be written to the output buffer. The output appears to fill each
> line without the display slowdown due to long displayed lines.
> And because hscroll is turned off, the text merely flows up the
> screen quickly.
Have you tried the (presumably) simpler approach of only inserting the
text one line at a time, i.e. accumulate the output in some undisplayed
"buffer area" (can be a buffer, a string, or a list of strings, this
last choice being probably the most efficient) until you see a \n and
then insert that text (upto and including the \n, so the cursor stays in
column 0 and doesn't risk triggering auto-hscroll-mode) while keeping
the rest in the "buffer area"?
Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-08 18:19 ` Stefan Monnier
@ 2013-01-11 14:40 ` Michael Mauger
2013-01-11 15:55 ` Stefan Monnier
0 siblings, 1 reply; 9+ messages in thread
From: Michael Mauger @ 2013-01-11 14:40 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Vitalie Spinu, Emacs Devel
>
>> The pre hook only activates if the mode is enabled and truncate-lines
>> is set. When active, it disables auto-hscroll-mode. It then appends
>> the output text to a temporary buffer and then returns a window's
>> width worth of characters of each line in the temp buffer to
>> be written to the output buffer. The output appears to fill each
>> line without the display slowdown due to long displayed lines.
>> And because hscroll is turned off, the text merely flows up the
>> screen quickly.
>
> Have you tried the (presumably) simpler approach of only inserting the
> text one line at a time, i.e. accumulate the output in some undisplayed
> "buffer area" (can be a buffer, a string, or a list of strings, this
> last choice being probably the most efficient) until you see a \n and
> then insert that text (upto and including the \n, so the cursor stays in
> column 0 and doesn't risk triggering auto-hscroll-mode) while keeping
> the rest in the "buffer area"?
>
>
> Stefan
>
I hate that after beating my head against the wall for a month, you can
say "Have you tried..." and I'm sitting here going "Duh!". ;-) Thanks.
You are correct that by only passing along the incoming text thru
(and including) the last newline of the preoutput text does reduce the
auto-hscroll-mode related flickering. The trick is detecting the prompt
at the end of the output to force the filter to flush everything. The
implementation is very straightforward just using a string to hold
what is left over from the prior iteration.
Comparing the results to not having the filter, is dramatic. I have a
query that produces about 200 rows of data x 8000 characters per
row (the database columns are waaaay too long for the data present,
but that's what I have to live with). Without the filter and
auto-hscroll-mode engaged, the results take nearly 30 seconds to
complete under Emacs. (It is nearly instantaneous outside of Emacs.)
With the filter you suggest, the results take about 8-10 seconds with
a noticeable stutter between each row. With the solution I had
developed (buffering the long lines in a buffer and restoring them at
the end of output), the results scroll by quickly in about 2-3 seconds,
but then it hesitates at the end (as it restores the long lines in the
buffer), for another 2-3 seconds. So just reducing the horizontal
scrolling is giving us the big payback and the more complex
gymnastics is probably not worth code cost.
Thank you again, Stefan. Thanks for the suggestion and clarifying my
thinking about how process output and display is handled in Emacs.
Your leadership and patience is appreciated.
I'll be adding this filtering to an existing output filter in sql.el.
-- Michael
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-11 14:40 ` Michael Mauger
@ 2013-01-11 15:55 ` Stefan Monnier
2013-01-13 8:14 ` Michael Mauger
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2013-01-11 15:55 UTC (permalink / raw)
To: Michael Mauger; +Cc: Vitalie Spinu, Emacs Devel
> but that's what I have to live with). Without the filter and
> auto-hscroll-mode engaged, the results take nearly 30 seconds to
> complete under Emacs. (It is nearly instantaneous outside of Emacs.)
> With the filter you suggest, the results take about 8-10 seconds with
> a noticeable stutter between each row. With the solution I had
> developed (buffering the long lines in a buffer and restoring them at
> the end of output), the results scroll by quickly in about 2-3 seconds,
> but then it hesitates at the end (as it restores the long lines in the
> buffer), for another 2-3 seconds. So just reducing the horizontal
> scrolling is giving us the big payback and the more complex
> gymnastics is probably not worth code cost.
Hmm... I'm wondering why the "one line at a time" approach ends up
slightly slower than your more complex approach. Using a single string
occurs an O(N^2) overhead (where N is the line length: we receive O(N)
packets per line and for each package we do a concat which costs O(N)),
so that might be the reason (which is why I suggested using a list of
strings, tho it makes detection of the prompt more cumbersome), but for
8KB lines it's not clear it would be that bad.
Could you M-x profiler-start ... M-x profiler-report around your tests
to see where the time is spent?
Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-11 15:55 ` Stefan Monnier
@ 2013-01-13 8:14 ` Michael Mauger
2013-01-13 16:46 ` Eli Zaretskii
2013-01-16 14:39 ` Stefan Monnier
0 siblings, 2 replies; 9+ messages in thread
From: Michael Mauger @ 2013-01-13 8:14 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Vitalie Spinu, Emacs Devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Sent: Friday, January 11, 2013 10:55 AM
>
>> but that's what I have to live with). Without the filter and
>> auto-hscroll-mode engaged, the results take nearly 30 seconds to
>> complete under Emacs. (It is nearly instantaneous outside of Emacs.)
>> With the filter you suggest, the results take about 8-10 seconds with
>> a noticeable stutter between each row. With the solution I had
>> developed (buffering the long lines in a buffer and restoring them at
>> the end of output), the results scroll by quickly in about 2-3 seconds,
>> but then it hesitates at the end (as it restores the long lines in the
>> buffer), for another 2-3 seconds. So just reducing the horizontal
>> scrolling is giving us the big payback and the more complex
>> gymnastics is probably not worth code cost.
>
> Hmm... I'm wondering why the "one line at a time" approach ends up
> slightly slower than your more complex approach. Using a single string
> occurs an O(N^2) overhead (where N is the line length: we receive O(N)
> packets per line and for each package we do a concat which costs O(N)),
> so that might be the reason (which is why I suggested using a list of
> strings, tho it makes detection of the prompt more cumbersome), but for
> 8KB lines it's not clear it would be that bad.
>
> Could you M-x profiler-start ... M-x profiler-report around your tests
> to see where the time is spent?
>
>
> Stefan
>
I ran several different configurations trying to identify important
criteria related to the display of this large block of text.
Testing ran a single database query that returns 289 rows of data
and 6000 characters per row. For a total of 1.7MB of data.
First, outside of Emacs, at the bash prompt on a GNU/Linux laptop.
$ time sqlite3 test.db <test_big.sql | wc
292 1684 1747492
real 0m0.175s
user0m0.140s
sys 0m0.004s
Basically, the database is not a constraint on performance.
I ran all tests with -Q. Each test was run in two display configurations:
* (NW) an 80x40 text terminal (GNOME Terminal 2.30.2) window, and
* (GUI) a similar sized X11 frame (GNU Emacs 24.3.50.1
(i686-pc-linux-gnu, X toolkit, Xaw3d scroll bars) of 2012-12-20)
(BZR revno:111283)
In each display environment I ran the tests with `truncate-lines' set to
`t' and then with it set to`nil'.
I then ran three different output filtering configurations:
* (BASE) Just the OOB sql.el module with it's output filters (eats
leading continuation prompts produced by multi-line commands)
* (SS) Simple filter that emits text thru the last newline and holds
the remainder for the next iteration. Avoids any horizontal scrolling.
* (HSC) My more complex minor mode that passes along the first 90
characters of each line and at the final prompt, it goes back and
inserts the remainder of each output line in the output buffer.
Below is a summary of the user experienced elapsed time of each of these
tests:
These numbers differ from what I had reported earlier but those were
based on my gut feel for the performance and based on a Cygwin/Win7
executable running on a much beefier Core i7 machine at work.
Display| GUI/X| Text/NW|
Truncate-lines| nil| t| nil| t|
---Filter---| -----| -----| -----| -----|
BASE| 3:43 | 5:51| 0:16 | 4:20 |
SS| 3:42 | 3:06 | 0:12 | 2:04 |
HSC| N/A | 0:07 | N/A | 0:04 |
* HSC is disabled when `truncate-lines' is nil; times in those cases
are the same as BASE
* HSC samples both include 1-2 seconds of hanging at the end as the
lines are updated by appending the filtered off-screen text
The two obvious takeaways from this is that GUIs are slower, and
truncate-lines set to non-nil can be painful.
I have the cpu profile saved for each of the tests and have included a
summary of some of them below. I've been staring at numbers for
the last three days so I'm getting a little cross-eyed. Let me know
if there is something more that would help you.
Here's the CPU profiler report for:
SS / NW / Trunc (2:04)
===============
- redisplay_internal (C function) 117989 97%
- jit-lock-function 1832 1%
- jit-lock-fontify-now 1832 1%
- byte-code 1820 1%
- run-hook-with-args 1820 1%
- font-lock-fontify-region 1820 1%
- font-lock-default-fontify-region 1816 1%
- font-lock-fontify-keywords-region 1812 1%
re-search-forward 1800 1%
font-lock-extend-region-wholelines 4 0%
font-lock-set-defaults 4 0%
line-beginning-position 8 0%
match-data 4 0%
- eval 28 0%
- if 20 0%
display-graphic-p 12 0%
frame-parameter 8 0%
- unless 4 0%
- if 4 0%
- display-graphic-p 4 0%
framep-on-display 4 0%
- menu-bar-update-buffers 16 0%
lookup-key 16 0%
- file-remote-p 12 0%
find-file-name-handler 12 0%
- keymap-canonicalize 7 0%
keymap-prompt 4 0%
- map-keymap 3 0%
#<compiled 0x2092fc9> 3 0%
- comint-output-filter 2511 2%
- run-hook-with-args 2150 1%
- comint-watch-for-password-prompt 1393 1%
string-match 1393 1%
- comint-postoutput-scroll-to-bottom 634 0%
recenter 611 0%
- get-buffer-window-list 8 0%
window-list-1 4 0%
vconcat 4 0%
- ansi-color-process-output 123 0%
- ansi-color-apply-on-region 123 0%
re-search-forward 123 0%
- sql-interactive-remove-continuation-prompt 273 0%
- if 270 0%
- progn 270 0%
- let 270 0%
- if 266 0%
string-match 181 0%
- while 77 0%
string-match 77 0%
- setq 4 0%
substring 4 0%
- setq 4 0%
concat 4 0%
string-match 60 0%
- jit-lock-after-change 4 0%
put-text-property 4 0%
comint-carriage-motion 4 0%
buffer-name 4 0%
SS / NW / NoTrunc (0:12)
=================
- redisplay_internal (C function) 9403 80%
- jit-lock-function 1823 15%
- jit-lock-fontify-now 1823 15%
- byte-code 1792 15%
- run-hook-with-args 1792 15%
- font-lock-fontify-region 1792 15%
- font-lock-default-fontify-region 1792 15%
- font-lock-fontify-keywords-region 1789 15%
re-search-forward 1785 15%
font-lock-extend-region-wholelines 3 0%
- run-with-timer 16 0%
- apply 12 0%
- run-at-time 12 0%
- timer-relative-time 8 0%
time-add 4 0%
mod 4 0%
current-time 4 0%
line-beginning-position 7 0%
text-property-any 4 0%
- eval 30 0%
- if 14 0%
frame-parameter 11 0%
display-graphic-p 3 0%
mode-line-frame-control 4 0%
mode-line-eol-desc 4 0%
- menu-bar-update-buffers 15 0%
lookup-key 8 0%
frame-or-buffer-changed-p 3 0%
- file-remote-p 8 0%
find-file-name-handler 8 0%
- keymap-canonicalize 8 0%
- map-keymap 8 0%
#<compiled 0x2092fc9> 4 0%
- comint-output-filter 2058 17%
- run-hook-with-args 1700 14%
- comint-watch-for-password-prompt 1373 11%
string-match 1373 11%
- comint-postoutput-scroll-to-bottom 179 1%
recenter 175 1%
get-buffer-window-list 4 0%
- ansi-color-process-output 148 1%
- ansi-color-apply-on-region 148 1%
re-search-forward 145 1%
- sql-interactive-remove-continuation-prompt 214 1%
- if 214 1%
- progn 211 1%
- let 211 1%
- if 201 1%
string-match 137 1%
- while 60 0%
string-match 60 0%
- setq 4 0%
substring 4 0%
- setq 10 0%
concat 10 0%
string-match 74 0%
comint-carriage-motion 19 0%
- jit-lock-after-change 11 0%
- run-hook-with-args 4 0%
- font-lock-extend-jit-lock-region-after-cha 4 0%
line-beginning-position 4 0%
byte-code 3 0%
move-overlay 4 0%
Automatic GC 162 1%
HSC / NW / Trunc (0:04)
================
- redisplay_internal (C function) 3501 48%
- jit-lock-function 386 5%
- jit-lock-fontify-now 386 5%
- byte-code 359 5%
- run-hook-with-args 359 5%
- font-lock-fontify-region 359 5%
- font-lock-default-fontify-region 359 5%
- font-lock-fontify-keywords-region 359 5%
re-search-forward 355 4%
make-marker 4 0%
- run-with-timer 15 0%
- apply 15 0%
- run-at-time 15 0%
- timer-relative-time 11 0%
time-add 7 0%
floor 4 0%
timer-set-function 4 0%
- eval 28 0%
- if 20 0%
frame-parameter 12 0%
- display-graphic-p 8 0%
framep-on-display 4 0%
- mode-line-eol-desc 8 0%
coding-system-eol-type-mnemonic 8 0%
keymap-canonicalize 11 0%
- menu-bar-update-buffers 8 0%
lookup-key 4 0%
frame-or-buffer-changed-p 4 0%
- file-remote-p 8 0%
find-file-name-handler 8 0%
- comint-output-filter 3185 44%
- run-hook-with-args 3084 43%
- sql-hscroll-post-output 2927 40%
- if 2927 40%
- progn 2904 40%
- let 2904 40%
- save-excursion 2904 40%
- while 2904 40%
- move-end-of-line 2852 39%
- line-move 2852 39%
- line-move-1 2852 39%
vertical-motion 2836 39%
- byte-code 12 0%
line-move-finish 12 0%
- insert 36 0%
- jit-lock-after-change 8 0%
put-text-property 4 0%
- apply 8 0%
propertize 4 0%
quote 4 0%
- save-current-buffer 16 0%
- setq 12 0%
- not 8 0%
- zerop 8 0%
forward-line 8 0%
line-end-position 4 0%
set-buffer 4 0%
- and 23 0%
- sql--hscroll-at-end-p 23 0%
- save-current-buffer 23 0%
- looking-back 23 0%
re-search-backward 19 0%
- comint-postoutput-scroll-to-bottom 133 1%
recenter 125 1%
vconcat 4 0%
select-window 4 0%
- comint-watch-for-password-prompt 12 0%
string-match 12 0%
- ansi-color-process-output 8 0%
- ansi-color-apply-on-region 8 0%
ansi-color-apply-overlay-face 4 0%
ansi-color--find-face 4 0%
- sql-hscroll-pre-output 55 0%
- if 55 0%
- let 55 0%
- save-current-buffer 55 0%
- sql--hscroll-copy-output 51 0%
- save-excursion 25 0%
insert 25 0%
- let* 19 0%
line-beginning-position 8 0%
- while 4 0%
- setq 4 0%
line-end-position 4 0%
line-end-position 3 0%
goto-char 7 0%
- looking-back 16 0%
re-search-backward 16 0%
- comint-carriage-motion 8 0%
line-beginning-position 4 0%
move-overlay 3 0%
- sql-interactive-remove-continuation-prompt 3 0%
- if 3 0%
- progn 3 0%
- let 3 0%
- setq 3 0%
concat 3 0%
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-13 8:14 ` Michael Mauger
@ 2013-01-13 16:46 ` Eli Zaretskii
2013-01-16 14:39 ` Stefan Monnier
1 sibling, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2013-01-13 16:46 UTC (permalink / raw)
To: Michael Mauger; +Cc: spinuvit, monnier, emacs-devel
> Date: Sun, 13 Jan 2013 00:14:49 -0800 (PST)
> From: Michael Mauger <mmaug@yahoo.com>
> Cc: Vitalie Spinu <spinuvit@gmail.com>, Emacs Devel <emacs-devel@gnu.org>
>
> In each display environment I ran the tests with `truncate-lines' set to
> `t' and then with it set to`nil'.
When it was non-nil, did you also disable auto-hscroll-mode?
Displaying an hscrolled windows disables redisplay optimizations, so
redisplay will be much slower (and it already is slow with such long
lines).
> The two obvious takeaways from this is that GUIs are slower, and
> truncate-lines set to non-nil can be painful.
That's almost trivial.
> I've been staring at numbers for the last three days so I'm getting
> a little cross-eyed. Let me know if there is something more that
> would help you.
AFAIU, the profiles say that redisplay takes the lion's share of the
time, and the less you trigger redisplay, the faster Emacs is. Is
that true? If so, this, too, should be almost obvious, since
displaying long lines is notoriously slow in Emacs.
Once again, why don't you collect the text in a buffer that is not
displayed until you actually want to present it to the user?
Also, if the text is known to be 7-bit ASCII, try displaying it in a
unibyte buffer, that should be faster in Emacs 24.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Deffering redisplay in COMINT
2013-01-13 8:14 ` Michael Mauger
2013-01-13 16:46 ` Eli Zaretskii
@ 2013-01-16 14:39 ` Stefan Monnier
1 sibling, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2013-01-16 14:39 UTC (permalink / raw)
To: Michael Mauger; +Cc: Vitalie Spinu, Emacs Devel
> I ran several different configurations trying to identify important
> criteria related to the display of this large block of text.
> Display | GUI/X | Text/NW|
> Truncate-lines | nil | t | nil | t|
> ---Filter--- | ----- | ----- | ----- | -----|
> BASE | 3:43 | 5:51 | 0:16 | 4:20 |
> SS | 3:42 | 3:06 | 0:12 | 2:04 |
> HSC | N/A | 0:07 | N/A | 0:04 |
From your tests, it seems clear that the problem is always redisplay
time, which is why the extra work of HSC pays off.
I think I can understand the difference between truncate and
non-truncate on a tty (the amount of buffer text redisplay has to
consider (i.e. (- (window-end) (window-start))) when refreshing the
display is larger (proportional to the line lengths) than with
wrap-around). But I don't understand why we don't see the same impact
in the GUI case. IOW I really don't understand the "3:42" of SS+GUI
with truncate-lines==nil. I'd expect it to be *much* lower (like 0:20
or so).
Maybe we could speed it up the 2:04 case with a redisplay optimization that
skips more quickly over the truncated part of the lines (special casing
the "easy common case where there's no before/after-string, no `display'
property, ...").
You could try and tweak the SS code further to reduce the number of
redisplays. E.g. not only you "wait for a complete line" but you also
"wait for the next second" so the buffer is only redisplayed once
a second.
Or you could try to do something halfway between SS and HSC: instead of
keeping the non-displayed part of lines in a separate buffer (as in
HSC), you do insert them (as in SS) but with an `invisible'
text-property set to t so that the redisplay can (hopefully) skip over
it very quickly.
Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-01-16 14:39 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-07 1:08 Deffering redisplay in COMINT Michael Mauger
2012-12-25 11:09 ` Vitalie Spinu
2013-01-06 8:09 ` Michael Mauger
2013-01-08 18:19 ` Stefan Monnier
2013-01-11 14:40 ` Michael Mauger
2013-01-11 15:55 ` Stefan Monnier
2013-01-13 8:14 ` Michael Mauger
2013-01-13 16:46 ` Eli Zaretskii
2013-01-16 14:39 ` Stefan Monnier
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.