* bug#44007: 26.3; Strange shell mode performance
@ 2020-10-15 9:53 Herman, Géza
2020-10-15 14:10 ` Eli Zaretskii
0 siblings, 1 reply; 23+ messages in thread
From: Herman, Géza @ 2020-10-15 9:53 UTC (permalink / raw)
To: 44007
I'm experiencing strange shell (comint) mode performance. If I cat a 10
MB file, it takes 1:20 to cat it. Emacs uses only 30% cpu. But, if I
press enter after I send the cat command, it speeds up, and it only
takes 8 sec (emacs cpu usage goes up to 100%).
Same thing: if I execute "seq 100000" in a small emacs window, it takes
~3 seconds. But, if I press enter after executing seq, it takes only 0.4
sec (this is not 100% reproducible, sometimes pressing enter doesn't
make a difference).
(I executed comint-clear-buffer before measurements)
It happens with 26.3 and ~3-week-old master branch as well, without any
extra config (emacs -Q).
In GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.20)
of 2020-05-17, modified by Debian built on x86-csail-01
Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
System Description: Debian GNU/Linux bullseye/sid
Recent messages:
Overwrite mode enabled in current buffer
Overwrite mode disabled in current buffer
Mark set [2 times]
Setting ‘send-mail-function’ temporarily since "emacs -q" would
overwrite customizations
Sending...
Mark set [2 times]
Sending via mail...
Sending...done
mwheel-scroll: Beginning of buffer [8 times]
mwheel-scroll: End of buffer [6 times]
mwheel-scroll: Beginning of buffer [6 times]
Configured using:
'configure --build x86_64-linux-gnu --prefix=/usr
--sharedstatedir=/var/lib --libexecdir=/usr/lib
--localstatedir=/var/lib --infodir=/usr/share/info
--mandir=/usr/share/man --enable-libsystemd --with-pop=yes
--enable-locallisppath=/etc/emacs:/usr/local/share/emacs/26.3/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/26.3/site-lisp:/usr/share/emacs/site-lisp
--with-sound=alsa --without-gconf --with-mailutils --build
x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib
--libexecdir=/usr/lib --localstatedir=/var/lib
--infodir=/usr/share/info --mandir=/usr/share/man --enable-libsystemd
--with-pop=yes
--enable-locallisppath=/etc/emacs:/usr/local/share/emacs/26.3/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/26.3/site-lisp:/usr/share/emacs/site-lisp
--with-sound=alsa --without-gconf --with-mailutils --with-x=yes
--with-x-toolkit=gtk3 --with-toolkit-scroll-bars 'CFLAGS=-g -O2
-fdebug-prefix-map=/build/emacs-mHAik2/emacs-26.3+1=.
-fstack-protector-strong
-Wformat -Werror=format-security -Wall' 'CPPFLAGS=-Wdate-time
-D_FORTIFY_SOURCE=2' LDFLAGS=-Wl,-z,relro'
Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS GLIB
NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM THREADS LIBSYSTEMD LCMS2
Important settings:
value of $LC_ALL: C.UTF-8
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: Lisp Interaction
Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
eldoc-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
line-number-mode: t
transient-mark-mode: t
Load-path shadows:
None found.
Features:
(mailalias mailclient browse-url cus-edit cus-start cus-load wid-edit
help-mode pp shadow sort mail-extr emacsbug message rmc puny seq
byte-opt gv bytecomp byte-compile cconv cl-loaddefs cl-lib dired
dired-loaddefs format-spec rfc822 mml easymenu mml-sec password-cache
epa derived epg epg-config gnus-util rmail rmail-loaddefs mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
elec-pair time-date mule-util tooltip eldoc electric uniquify ediff-hook
vc-hooks lisp-float-type mwheel term/x-win x-win term/common-win x-dnd
tool-bar dnd fontset image regexp-opt fringe tabulated-list replace
newcomment text-mode elisp-mode lisp-mode prog-mode register page
menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock
font-lock syntax facemenu font-core term/tty-colors frame cl-generic
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite charscript charprop
case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer
cl-preloaded nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote threads dbusbind
inotify lcms2 dynamic-setting system-font-setting font-render-setting
move-toolbar gtk x-toolkit x multi-tty make-network-process emacs)
Memory information:
((conses 16 121337 21158)
(symbols 48 22080 0)
(miscs 40 64 154)
(strings 32 32731 1152)
(string-bytes 1 852243)
(vectors 16 15681)
(vector-slots 8 516540 10022)
(floats 8 64 228)
(intervals 56 612 0)
(buffers 992 14))
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 9:53 bug#44007: 26.3; Strange shell mode performance Herman, Géza
@ 2020-10-15 14:10 ` Eli Zaretskii
2020-10-15 14:34 ` Herman, Geza
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Eli Zaretskii @ 2020-10-15 14:10 UTC (permalink / raw)
To: Herman, Géza; +Cc: 44007
> From: Herman@debbugs.gnu.org, Géza <geza.herman@gmail.com>
> Date: Thu, 15 Oct 2020 11:53:16 +0200
>
> I'm experiencing strange shell (comint) mode performance. If I cat a 10
> MB file, it takes 1:20 to cat it. Emacs uses only 30% cpu. But, if I
> press enter after I send the cat command, it speeds up, and it only
> takes 8 sec (emacs cpu usage goes up to 100%).
>
> Same thing: if I execute "seq 100000" in a small emacs window, it takes
> ~3 seconds. But, if I press enter after executing seq, it takes only 0.4
> sec (this is not 100% reproducible, sometimes pressing enter doesn't
> make a difference).
> (I executed comint-clear-buffer before measurements)
Can you please describe a detailed reproduction recipe, starting from
"emacs -Q"? It is not exactly clear from the above whether you do
this in a shell-mode buffer or in some other mode, where exactly do
you press Enter, etc. A detailed recipe will resolve all those
unclear aspects.
Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:10 ` Eli Zaretskii
@ 2020-10-15 14:34 ` Herman, Geza
2020-10-16 8:25 ` Andreas Röhler
` (2 more replies)
2020-10-16 10:44 ` Herman, Géza
2020-10-17 12:48 ` Herman, Géza
2 siblings, 3 replies; 23+ messages in thread
From: Herman, Geza @ 2020-10-15 14:34 UTC (permalink / raw)
To: Eli Zaretskii, Herman; +Cc: 44007
Sure!
1. execute emacs by "emacs -Q"
2. M-x shell RET
3. in the shell, execute "seq 100000" (or cat a large file)
4. immediately after you hit enter on "seq 100000" press enter again
It doesn't reproduce 100% unfortunately. It seems that if it doesn't
reproduce, you need to start from step 1., so it has a higher chance to
happen.
Another strange thing is that enter can have the opposite effect as
well: if I press it during "seq 100000" several times (not immediately
after "seq 100000", but after ~1 sec), it can make seq slower. Instead
of the usual 3-4 sec, it slows down to >10 sec.
(I measured by "time seq 100000"). It seems that the more enter I press,
the slower it gets. But maybe it's a different issue.
On 2020-10-15 16:10, Eli Zaretskii wrote:
>> From: Herman@debbugs.gnu.org, Géza <geza.herman@gmail.com>
>> Date: Thu, 15 Oct 2020 11:53:16 +0200
>>
>> I'm experiencing strange shell (comint) mode performance. If I cat a 10
>> MB file, it takes 1:20 to cat it. Emacs uses only 30% cpu. But, if I
>> press enter after I send the cat command, it speeds up, and it only
>> takes 8 sec (emacs cpu usage goes up to 100%).
>>
>> Same thing: if I execute "seq 100000" in a small emacs window, it takes
>> ~3 seconds. But, if I press enter after executing seq, it takes only 0.4
>> sec (this is not 100% reproducible, sometimes pressing enter doesn't
>> make a difference).
>> (I executed comint-clear-buffer before measurements)
> Can you please describe a detailed reproduction recipe, starting from
> "emacs -Q"? It is not exactly clear from the above whether you do
> this in a shell-mode buffer or in some other mode, where exactly do
> you press Enter, etc. A detailed recipe will resolve all those
> unclear aspects.
>
> Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:34 ` Herman, Geza
@ 2020-10-16 8:25 ` Andreas Röhler
2022-01-28 15:26 ` Lars Ingebrigtsen
2023-11-05 16:46 ` Herman, Géza
2 siblings, 0 replies; 23+ messages in thread
From: Andreas Röhler @ 2020-10-16 8:25 UTC (permalink / raw)
To: 44007
On 15.10.20 16:34, Herman, Geza wrote:
> Sure!
>
> 1. execute emacs by "emacs -Q"
> 2. M-x shell RET
> 3. in the shell, execute "seq 100000" (or cat a large file)
> 4. immediately after you hit enter on "seq 100000" press enter again
>
> It doesn't reproduce 100% unfortunately. It seems that if it doesn't
> reproduce, you need to start from step 1., so it has a higher chance
> to happen.
>
> Another strange thing is that enter can have the opposite effect as
> well: if I press it during "seq 100000" several times (not immediately
> after "seq 100000", but after ~1 sec), it can make seq slower. Instead
> of the usual 3-4 sec, it slows down to >10 sec.
> (I measured by "time seq 100000"). It seems that the more enter I
> press, the slower it gets. But maybe it's a different issue.
>
> On 2020-10-15 16:10, Eli Zaretskii wrote:
>>> From: Herman@debbugs.gnu.org, Géza <geza.herman@gmail.com>
>>> Date: Thu, 15 Oct 2020 11:53:16 +0200
>>>
>>> I'm experiencing strange shell (comint) mode performance. If I cat a 10
>>> MB file, it takes 1:20 to cat it. Emacs uses only 30% cpu. But, if I
>>> press enter after I send the cat command, it speeds up, and it only
>>> takes 8 sec (emacs cpu usage goes up to 100%).
>>>
>>> Same thing: if I execute "seq 100000" in a small emacs window, it takes
>>> ~3 seconds. But, if I press enter after executing seq, it takes only
>>> 0.4
>>> sec (this is not 100% reproducible, sometimes pressing enter doesn't
>>> make a difference).
>>> (I executed comint-clear-buffer before measurements)
>> Can you please describe a detailed reproduction recipe, starting from
>> "emacs -Q"? It is not exactly clear from the above whether you do
>> this in a shell-mode buffer or in some other mode, where exactly do
>> you press Enter, etc. A detailed recipe will resolve all those
>> unclear aspects.
>>
>> Thanks.
>
>
>
>
Can't reproduce example "seq..." with GNU Emacs 28.0.50 (build 1,
i686-pc-linux-gnu, GTK+ Version 3.14.5, cairo version 1.14.0) of 2020-06-10
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:10 ` Eli Zaretskii
2020-10-15 14:34 ` Herman, Geza
@ 2020-10-16 10:44 ` Herman, Géza
2020-10-16 10:55 ` Eli Zaretskii
2020-10-17 12:48 ` Herman, Géza
2 siblings, 1 reply; 23+ messages in thread
From: Herman, Géza @ 2020-10-16 10:44 UTC (permalink / raw)
To: 44007
[-- Attachment #1: Type: text/plain, Size: 718 bytes --]
It reproduces for me, both 26.3 and 28.0.50. And both for the X and
console version (by console version, I mean the usual version, but with
DISPLAY unset).
I attached a text file (hopefully it gets through).
cat-ing this file takes ~18 sec. But with enter, it takes just ~3 sec
(these measurements are done with the console version). It behaves like
this 100% of the time (it's a more reliable test than the "seq" test).
And it also speeds up, if I don't press enter, but constantly move the
mouse (using the X version).
It seems that emacs waits for some kind of event here (hence the low cpu
utilization). But if there's some event (mouse, or an unprocessed
input), then it speeds up (and uses 100% cpu).
[-- Attachment #2: test.txt.xz --]
[-- Type: application/x-xz, Size: 63204 bytes --]
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-16 10:44 ` Herman, Géza
@ 2020-10-16 10:55 ` Eli Zaretskii
2020-10-16 12:23 ` Herman, Géza
0 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2020-10-16 10:55 UTC (permalink / raw)
To: Herman, Géza; +Cc: 44007
> From: Herman@debbugs.gnu.org, Géza <geza.herman@gmail.com>
> Date: Fri, 16 Oct 2020 12:44:32 +0200
>
> It reproduces for me, both 26.3 and 28.0.50. And both for the X and
> console version (by console version, I mean the usual version, but with
> DISPLAY unset).
>
> I attached a text file (hopefully it gets through).
>
> cat-ing this file takes ~18 sec. But with enter, it takes just ~3 sec
> (these measurements are done with the console version). It behaves like
> this 100% of the time (it's a more reliable test than the "seq" test).
Does it help to play with the value of process-adaptive-read-buffering?
Or with read-process-output-max?
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-16 10:55 ` Eli Zaretskii
@ 2020-10-16 12:23 ` Herman, Géza
0 siblings, 0 replies; 23+ messages in thread
From: Herman, Géza @ 2020-10-16 12:23 UTC (permalink / raw)
To: 44007
> Does it help to play with the value of process-adaptive-read-buffering?
> Or with read-process-output-max?
It seems it doesn't. I tried all 4 combinations of
read-process-output-max = 4096/1 MB and process-adaptive-read-buffering
= nil/t, emacs behaves the same.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:10 ` Eli Zaretskii
2020-10-15 14:34 ` Herman, Geza
2020-10-16 10:44 ` Herman, Géza
@ 2020-10-17 12:48 ` Herman, Géza
2 siblings, 0 replies; 23+ messages in thread
From: Herman, Géza @ 2020-10-17 12:48 UTC (permalink / raw)
To: 44007
I've debugged the issue a little bit, and the cause of it is
process-adaptive-read-buffering indeed. I misused this variable before:
I tried to set it to nil before executing "cat", but it needs to be set
before "M-x shell".
Setting it to nil completely fixes the issue. If its value is "t", my
"cat test.txt" runs in 18 sec. Setting it to "nil", cat runs in ~2 sec.
Looking at the logic which does adaptive reading, I see why it can be
suboptimal. If a process sends less than 256 bytes at first, then delay
is increased, and it will be decreased only if the process can send
bytes which completely fills the buffer. But this may never be true
(because some other part of the system already throttles the process,
because emacs didn't read enough from it - I suppose this can depend on
the value read-process-output-max).
The issue can be made less severe by modifying emacs_intr_read to read
as much as data fit into the buffer (execute read() until it reports
failure/EOF). It solves the issue completely for me, if
read-process-output-max is 4096. If it's 1MB, this modification makes
the issue less severe: "cat test.txt" runs in 6 sec.
Here's the modification I did to emacs_intr_read, put this after the
do/while loop:
if (result > 0) {
for (;;) {
ssize_t r = read(fd, buf+result, nbyte-result);
if (r<=0) break;
if (interruptible) maybe_quit();
result += r;
}
}
(I'm not saying that this is the correct solution, I put this here so
you can repro my results)
The reason that it's needed that read() returns 4095 for some reason,
even though nbyte is 4096. An additional read() call will provide the
missing 1 byte. As far as I know, this is a valid and allowed, yet
strange behavior. I'm not sure what causes it.
I think that the logic around decreasing the delay is not good. The
current "decrease delay when buffer is full" is a fragile condition. To
me, it seems logical to clear/decrease delay if more than 256 bytes
arrived. It may not be 100% optimal, but it's near to it. On the other
hand, the current behavior can cause severe performance problems for
fast streams. Having read-process-output-max a large value is essential:
"cat test.txt" runs in 0.3 sec, when this value is 1MB (adaptive is
turned off). If read-process-output-max is 4K, it runs in 1.4 sec
(adaptive is turned off).
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:34 ` Herman, Geza
2020-10-16 8:25 ` Andreas Röhler
@ 2022-01-28 15:26 ` Lars Ingebrigtsen
2022-01-28 22:33 ` Herman, Géza
2023-11-05 16:46 ` Herman, Géza
2 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2022-01-28 15:26 UTC (permalink / raw)
To: Herman, Geza; +Cc: 44007, Herman
"Herman, Geza" <geza.herman@gmail.com> writes:
> 1. execute emacs by "emacs -Q"
> 2. M-x shell RET
> 3. in the shell, execute "seq 100000" (or cat a large file)
> 4. immediately after you hit enter on "seq 100000" press enter again
(I'm going through old bug reports that unfortunately weren't resolved
at the time.)
I was unable to reproduce this issue, either with or without
(setq process-adaptive-read-buffering nil)
before `M-x shell'. Are you still seeing this issue in more recent
versions of Emacs?
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2022-01-28 15:26 ` Lars Ingebrigtsen
@ 2022-01-28 22:33 ` Herman, Géza
2022-01-29 6:52 ` Eli Zaretskii
2022-01-29 14:38 ` Lars Ingebrigtsen
0 siblings, 2 replies; 23+ messages in thread
From: Herman, Géza @ 2022-01-28 22:33 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 44007, Herman
Yes, it still happens on current master for me.
By default, "seq 100000" takes ~3 sec. Pressing enter immediately after
executing the seq can make seq to take ~0.4 sec. Or if press enter
during "seq" several times, time can easily increase to >20 sec (this
issue seems to be related to bidi-paragraph-direction. If I set it to
left-to-right, this doesn't happen anymore - I've no idea why it matters).
How much time does "seq 100000" take for you? Does it use 100% cpu?
Maybe the OS matters here (how the read() syscall behaves): I'm on
debian linux (sid).
On 2022-01-28 16:26, Lars Ingebrigtsen wrote:
> "Herman, Geza" <geza.herman@gmail.com> writes:
>
>> 1. execute emacs by "emacs -Q"
>> 2. M-x shell RET
>> 3. in the shell, execute "seq 100000" (or cat a large file)
>> 4. immediately after you hit enter on "seq 100000" press enter again
> (I'm going through old bug reports that unfortunately weren't resolved
> at the time.)
>
> I was unable to reproduce this issue, either with or without
>
> (setq process-adaptive-read-buffering nil)
>
> before `M-x shell'. Are you still seeing this issue in more recent
> versions of Emacs?
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2022-01-28 22:33 ` Herman, Géza
@ 2022-01-29 6:52 ` Eli Zaretskii
2022-01-29 14:38 ` Lars Ingebrigtsen
1 sibling, 0 replies; 23+ messages in thread
From: Eli Zaretskii @ 2022-01-29 6:52 UTC (permalink / raw)
To: Herman, Géza; +Cc: 44007, larsi, Herman
> Cc: Eli Zaretskii <eliz@gnu.org>, Herman@debbugs.gnu.org,
> 44007@debbugs.gnu.org
> From: Herman, Géza <geza.herman@gmail.com>
> Date: Fri, 28 Jan 2022 23:33:47 +0100
>
> Yes, it still happens on current master for me.
>
> By default, "seq 100000" takes ~3 sec. Pressing enter immediately after
> executing the seq can make seq to take ~0.4 sec. Or if press enter
> during "seq" several times, time can easily increase to >20 sec (this
> issue seems to be related to bidi-paragraph-direction. If I set it to
> left-to-right, this doesn't happen anymore - I've no idea why it matters).
If setting bidi-paragraph-direction to left-to-right fixes the
slowdown, then this is expected and not a bug. When
bidi-paragraph-direction is nil, Emacs needs to determine the
paragraph direction from the strong directional characters in the
preceding paragraph of text, but "seq 100000" produces a long
paragraph that has no strong directional characters at all (digits
have "weak" directionality).
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2022-01-28 22:33 ` Herman, Géza
2022-01-29 6:52 ` Eli Zaretskii
@ 2022-01-29 14:38 ` Lars Ingebrigtsen
2022-01-29 16:10 ` Herman, Géza
1 sibling, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2022-01-29 14:38 UTC (permalink / raw)
To: Herman, Géza; +Cc: 44007
"Herman, Géza" <geza.herman@gmail.com> writes:
> How much time does "seq 100000" take for you? Does it use 100% cpu?
emacs -Q
M-x shell
seq 100000
takes very little time for me -- perhaps 0.2s?
If I add a zero, it takes about five seconds, but hitting RET in the
middle doesn't affect the speed.
> Maybe the OS matters here (how the read() syscall behaves): I'm on
> debian linux (sid).
I'm on Debian/bookworm...
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2022-01-29 14:38 ` Lars Ingebrigtsen
@ 2022-01-29 16:10 ` Herman, Géza
0 siblings, 0 replies; 23+ messages in thread
From: Herman, Géza @ 2022-01-29 16:10 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 44007
It's already fast on your machine, so that's why pressing RET doesn't
make a difference.
I tried this on a mac with Emacs 27, and it's easily reproduceable
(easier than on linux). It seems that on mac, the exact timing of the
extra RET doesn't matter. Even if it's halfway printing the numbers,
pressing RET speeds up the remaining part. On linux, I have to press RET
immediately after executing the command, otherwise it doesn't become faster.
But I've found something right now: this issue is dependent on the
shell. With zsh, this happens. With bash, it doesn't. Weird. So it seems
that zsh sets something which makes this issue to appear. Nevertheless,
I think emacs_intr_read() is not ideal, it should handle the case if
multiple read() calls needed to gather all the available data (I've been
using emacs with my hacky patch for more than a year, I didn't notice
any problems with it).
On 2022-01-29 15:38, Lars Ingebrigtsen wrote:
> "Herman, Géza" <geza.herman@gmail.com> writes:
>
>> How much time does "seq 100000" take for you? Does it use 100% cpu?
> emacs -Q
> M-x shell
> seq 100000
>
> takes very little time for me -- perhaps 0.2s?
>
> If I add a zero, it takes about five seconds, but hitting RET in the
> middle doesn't affect the speed.
>
>> Maybe the OS matters here (how the read() syscall behaves): I'm on
>> debian linux (sid).
> I'm on Debian/bookworm...
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2020-10-15 14:34 ` Herman, Geza
2020-10-16 8:25 ` Andreas Röhler
2022-01-28 15:26 ` Lars Ingebrigtsen
@ 2023-11-05 16:46 ` Herman, Géza
2023-11-06 12:08 ` Eli Zaretskii
2 siblings, 1 reply; 23+ messages in thread
From: Herman, Géza @ 2023-11-05 16:46 UTC (permalink / raw)
To: Eli Zaretskii, Herman; +Cc: 44007
I think I found another thing which is needed: tty echo must be enabled.
With bash, echo is disabled by default, so the issue doesn't happen.
With zsh, echo is enabled by default, and the issue happens (I'm not
sure why zsh turns on echo).
So either one has to use zsh to repro the issue, or use these updated steps:
1. emacs -Q
2. M-x shell RET
3. stty echo
4. seq 100000
With echo disabled, "seq 100000" takes ~0.2 sec. With echo enabled, it
takes 3 sec (and pressing RET immediately after executing seq makes it
fast).
On 10/15/20 16:34, Herman, Geza wrote:
> Sure!
>
> 1. execute emacs by "emacs -Q"
> 2. M-x shell RET
> 3. in the shell, execute "seq 100000" (or cat a large file)
> 4. immediately after you hit enter on "seq 100000" press enter again
>
> It doesn't reproduce 100% unfortunately. It seems that if it doesn't
> reproduce, you need to start from step 1., so it has a higher chance
> to happen.
>
> Another strange thing is that enter can have the opposite effect as
> well: if I press it during "seq 100000" several times (not immediately
> after "seq 100000", but after ~1 sec), it can make seq slower. Instead
> of the usual 3-4 sec, it slows down to >10 sec.
> (I measured by "time seq 100000"). It seems that the more enter I
> press, the slower it gets. But maybe it's a different issue.
>
> On 2020-10-15 16:10, Eli Zaretskii wrote:
>>> From: Herman@debbugs.gnu.org, Géza <geza.herman@gmail.com>
>>> Date: Thu, 15 Oct 2020 11:53:16 +0200
>>>
>>> I'm experiencing strange shell (comint) mode performance. If I cat a 10
>>> MB file, it takes 1:20 to cat it. Emacs uses only 30% cpu. But, if I
>>> press enter after I send the cat command, it speeds up, and it only
>>> takes 8 sec (emacs cpu usage goes up to 100%).
>>>
>>> Same thing: if I execute "seq 100000" in a small emacs window, it takes
>>> ~3 seconds. But, if I press enter after executing seq, it takes only
>>> 0.4
>>> sec (this is not 100% reproducible, sometimes pressing enter doesn't
>>> make a difference).
>>> (I executed comint-clear-buffer before measurements)
>> Can you please describe a detailed reproduction recipe, starting from
>> "emacs -Q"? It is not exactly clear from the above whether you do
>> this in a shell-mode buffer or in some other mode, where exactly do
>> you press Enter, etc. A detailed recipe will resolve all those
>> unclear aspects.
>>
>> Thanks.
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-05 16:46 ` Herman, Géza
@ 2023-11-06 12:08 ` Eli Zaretskii
2023-11-06 12:28 ` Herman, Géza
0 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2023-11-06 12:08 UTC (permalink / raw)
To: Herman Géza; +Cc: 44007
> Date: Sun, 5 Nov 2023 17:46:15 +0100
> From: Herman, Géza <geza.herman@gmail.com>
> Cc: 44007@debbugs.gnu.org
>
> I think I found another thing which is needed: tty echo must be enabled.
> With bash, echo is disabled by default, so the issue doesn't happen.
> With zsh, echo is enabled by default, and the issue happens (I'm not
> sure why zsh turns on echo).
>
> So either one has to use zsh to repro the issue, or use these updated steps:
> 1. emacs -Q
> 2. M-x shell RET
> 3. stty echo
> 4. seq 100000
>
> With echo disabled, "seq 100000" takes ~0.2 sec. With echo enabled, it
> takes 3 sec (and pressing RET immediately after executing seq makes it
> fast).
I'm not sure what exactly are we trying to do here. AFAIU, at least 2
variables were discovered that can speed up this example, so what else
has to be done? Is there any bug here, and if so, what is the bug?
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 12:08 ` Eli Zaretskii
@ 2023-11-06 12:28 ` Herman, Géza
2023-11-06 13:22 ` Eli Zaretskii
0 siblings, 1 reply; 23+ messages in thread
From: Herman, Géza @ 2023-11-06 12:28 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 44007, Herman Géza
Eli Zaretskii <eliz@gnu.org> writes:
> I'm not sure what exactly are we trying to do here. AFAIU, at
> least 2
> variables were discovered that can speed up this example, so
> what else
> has to be done? Is there any bug here, and if so, what is the
> bug?
The bug is that if echo is enabled, emacs 'shell' gives a much
worse performance. And it has no apparent reason why it should be
the case.
Also, there is weird behavior around event handling (why does a
RET speed up I/O?). I think that this behavior suggests that
there is some bug in Emacs. At least I don't consider this a
normal behavior.
I don't think that the solution is that zsh users should set these
variables. It makes much more sense to fix Emacs so this doesn't
happen in the first place.
I'd like to also mention that my hacky solution not just fixes the
problem, but also improves shell's performance, even with the
mentioned variables set. As far as I know POSIX programming,
read() should always be called in a loop, if one wants to read N
bytes (even in the successful case). Emacs doesn't have this in
emacs_intr_read, that causes the problem.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 12:28 ` Herman, Géza
@ 2023-11-06 13:22 ` Eli Zaretskii
2023-11-06 13:37 ` Herman, Géza
0 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2023-11-06 13:22 UTC (permalink / raw)
To: Herman Géza; +Cc: 44007
> From: Herman, Géza <geza.herman@gmail.com>
> Cc: Herman Géza <geza.herman@gmail.com>,
> 44007@debbugs.gnu.org
> Date: Mon, 06 Nov 2023 13:28:15 +0100
>
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > I'm not sure what exactly are we trying to do here. AFAIU, at
> > least 2
> > variables were discovered that can speed up this example, so
> > what else
> > has to be done? Is there any bug here, and if so, what is the
> > bug?
>
> The bug is that if echo is enabled, emacs 'shell' gives a much
> worse performance.
I'm trying to understand why would we consider that a bug. There will
always be ways to make Lisp programs run slower or faster by tweaking
some variables, and the defaults are not always capable of providing
the best performance in every possible situation.
> And it has no apparent reason why it should be the case.
You (or anyone else) should of course feel free to investigate and try
to find out what are the specific reasons which make Emacs slower in
some cases and faster in others. But that doesn't necessarily
constitutes a bug, IMO.
> I'd like to also mention that my hacky solution not just fixes the
> problem, but also improves shell's performance, even with the
> mentioned variables set. As far as I know POSIX programming,
> read() should always be called in a loop, if one wants to read N
> bytes (even in the successful case). Emacs doesn't have this in
> emacs_intr_read, that causes the problem.
We've arrived at the current code after a lot of iterations, and it
has to handle many different uses. It doesn't surprise me a bit that
you can find a change which speeds up Emacs in some particular case,
but what about all the other cases?
How about if you run with this change for a few weeks or so, and see
if it doesn't cause problems elsewhere? maybe also others will try
using it in their use patterns and report back. Then we will at least
have some data regarding the effects of the change you propose.
Of course, if someone comes with a less hacky proposal, it would be
even better.
Also, please be sure to try Emacs 30, as I believe some changes were
done there recently.
Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 13:22 ` Eli Zaretskii
@ 2023-11-06 13:37 ` Herman, Géza
2023-11-06 14:40 ` Eli Zaretskii
2023-11-06 22:47 ` Dmitry Gutov
0 siblings, 2 replies; 23+ messages in thread
From: Herman, Géza @ 2023-11-06 13:37 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 44007, Herman Géza
Eli Zaretskii <eliz@gnu.org> writes:
>> The bug is that if echo is enabled, emacs 'shell' gives a much
>> worse performance.
>
> I'm trying to understand why would we consider that a bug.
> There will
> always be ways to make Lisp programs run slower or faster by
> tweaking
> some variables, and the defaults are not always capable of
> providing
> the best performance in every possible situation.
I think it is a bug because Emacs doesn't try to read again if one
read() was successful. My hacky solution fixes that. With the
extra cost of one read syscall. But we can do better: we can
avoid it if the first read call already read 'nbyte' bytes, then
there is no need to call another read().
Also, it a bug, because it's not logical (what does tty echo have
anything to do with the performance of reading process output?),
and the effect it causes is huge. We aren't talking about
something like 10% difference, but 1500%: 3 sec vs. 0.2 sec.
> You (or anyone else) should of course feel free to investigate
> and try
> to find out what are the specific reasons which make Emacs
> slower in
> some cases and faster in others. But that doesn't necessarily
> constitutes a bug, IMO.
I already did, see my comment about read() returning with 4095,
instead of 4096. Not a deep investigation, because I stopped
investigating it when I realized that read() is not called in a
loop, which is clearly a bug to me (as far as I understand how
read should be used according to POSIX. I'm not a unix hacker, I
may be wrong).
Tbh, I don't really understand the idea behind
process-adaptive-read-buffering. Why is this setting there? If a
process generates lot of output, it doesn't do anything useful.
If a process is slow, then this approach may save some system
calls (and other processing in emacs), but as the process slowly
generates output, it should already be quick to process. When
does it do something useful in a real world usage? Some packages
had to turn this setting off because they noticed that it makes
performance worse. If its usefulness is OS dependent, maybe it'd
make sense to enable it only on platforms where it make sense?
>> I'd like to also mention that my hacky solution not just fixes
>> the
>> problem, but also improves shell's performance, even with the
>> mentioned variables set. As far as I know POSIX programming,
>> read() should always be called in a loop, if one wants to read
>> N
>> bytes (even in the successful case). Emacs doesn't have this
>> in
>> emacs_intr_read, that causes the problem.
>
> We've arrived at the current code after a lot of iterations, and
> it
> has to handle many different uses. It doesn't surprise me a bit
> that
> you can find a change which speeds up Emacs in some particular
> case,
> but what about all the other cases?
If the intention of emacs_intr_read is to read nbytes bytes (if
that many is available), then the current code doesn't do that
correctly. This is not about handling different uses cases, but
simply using read() correctly. In the worst case, and OS is
allowed to give data byte by byte, where each read() call returns
just one byte. In this case, Emacs will read the output one byte
per render frame (or something like that, or I don't know how
emacs works in this regard). I think something similar happens
here: 4095 bytes is returned, because supposedly originally it was
4096, but something in the kernel/libc/whatever shaved off 1 byte
for some reason (that's just my theory). But returning with 4095
doesn't mean that's all that available. Emacs could read further,
but it doesn't.
> How about if you run with this change for a few weeks or so, and
> see
> if it doesn't cause problems elsewhere? maybe also others will
> try
> using it in their use patterns and report back. Then we will at
> least
> have some data regarding the effects of the change you propose.
I've been using this modification since I created this bug (many
years). I didn't notice any problems with it.
> Of course, if someone comes with a less hacky proposal, it would
> be
> even better.
I just call it hacky, because I just threw it together in several
minutes or so. But in my opinion that idea is OK (read as long as
possible). It's just the implementation that could be improved
(don't call read() again if nbytes already arrived, and there are
maybe other things).
> Also, please be sure to try Emacs 30, as I believe some changes
> were
> done there recently.
I've tried a 1-week-old master, the exact same thing happens.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 13:37 ` Herman, Géza
@ 2023-11-06 14:40 ` Eli Zaretskii
2023-11-06 15:00 ` Herman, Géza
2023-11-06 22:47 ` Dmitry Gutov
1 sibling, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2023-11-06 14:40 UTC (permalink / raw)
To: Herman Géza; +Cc: 44007
> From: Herman, Géza <geza.herman@gmail.com>
> Cc: Herman Géza <geza.herman@gmail.com>,
> 44007@debbugs.gnu.org
> Date: Mon, 06 Nov 2023 14:37:52 +0100
>
>
> I think it is a bug because Emacs doesn't try to read again if one
> read() was successful.
I believe reading again immediately could make Emacs unresponsive for
prolonged periods of time. We are talking about reading sub-process
output asynchronously, which means we must not read in a tight loop,
because that would have the same effect as calling a subprocess
synchronously and waiting for it to finish.
Even in this particular scenario, the user should be able to switch to
another buffer and issue commands, while Emacs is reading from the
shell or some program invoked from the shell.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 14:40 ` Eli Zaretskii
@ 2023-11-06 15:00 ` Herman, Géza
2023-11-06 16:52 ` Eli Zaretskii
0 siblings, 1 reply; 23+ messages in thread
From: Herman, Géza @ 2023-11-06 15:00 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 44007, Herman Géza
Eli Zaretskii <eliz@gnu.org> writes:
> I believe reading again immediately could make Emacs
> unresponsive for
> prolonged periods of time. We are talking about reading
> sub-process
> output asynchronously, which means we must not read in a tight
> loop,
> because that would have the same effect as calling a subprocess
> synchronously and waiting for it to finish.
>
> Even in this particular scenario, the user should be able to
> switch to
> another buffer and issue commands, while Emacs is reading from
> the
> shell or some program invoked from the shell.
I thought that the fd is nonblocking here. But even if it's not,
how does Emacs determine nbyte parameter? Because I suppose it
should be at most as large as the available data in the fd. If
not, then emacs_intr_read already has the chance of blocking
anyway without the loop.
Also, I have the loop in place for years, and didn't notice any
problems.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 15:00 ` Herman, Géza
@ 2023-11-06 16:52 ` Eli Zaretskii
2023-11-06 17:25 ` Herman, Géza
0 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2023-11-06 16:52 UTC (permalink / raw)
To: Herman Géza; +Cc: 44007
> From: Herman, Géza <geza.herman@gmail.com>
> Cc: Herman Géza <geza.herman@gmail.com>,
> 44007@debbugs.gnu.org
> Date: Mon, 06 Nov 2023 16:00:00 +0100
>
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> > I believe reading again immediately could make Emacs unresponsive
> > for prolonged periods of time. We are talking about reading
> > sub-process output asynchronously, which means we must not read in
> > a tight loop, because that would have the same effect as calling a
> > subprocess synchronously and waiting for it to finish.
> >
> > Even in this particular scenario, the user should be able to
> > switch to another buffer and issue commands, while Emacs is
> > reading from the shell or some program invoked from the shell.
>
> I thought that the fd is nonblocking here.
That doesn't matter here. The problem is not with blocking in 'read',
the problem is with calling one 'read' after another without letting
Emacs process the foreground input events.
> But even if it's not, how does Emacs determine nbyte parameter?
It's a parameter, which is exposed to Lisp, so can be controlled, but
otherwise is not based on anything.
> Because I suppose it should be at most as large as the available
> data in the fd.
Emacs doesn't know how much is available, it only knows that some
positive amount is available.
> If not, then emacs_intr_read already has the chance of blocking
> anyway without the loop.
Again, blocking is not the issue, see above.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 16:52 ` Eli Zaretskii
@ 2023-11-06 17:25 ` Herman, Géza
0 siblings, 0 replies; 23+ messages in thread
From: Herman, Géza @ 2023-11-06 17:25 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 44007, Herman Géza
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Herman, Géza <geza.herman@gmail.com>
>>
>> I thought that the fd is nonblocking here.
>
> That doesn't matter here. The problem is not with blocking in
> 'read',
> the problem is with calling one 'read' after another without
> letting
> Emacs process the foreground input events.
I see. But this loop only loops until either there are no more
bytes, or it reaches 'nbytes'. Unless the OS splits the available
output into very tiny bits, this shouldn't be a problem. But that
would be a bad behavior from the OS part. And even if the data is
splitted into tiny bits, the only extra time we pay for is the
overhead of the extra read() calls. Maybe for some OS's this can
be significant, I'm not sure. For my case, data is only splitted
into two pieces (4095 + 1), I don't think this causes any serious
problem, even theoretically.
But anyways. Before I added this hacky solution to Emacs, I had
been an Emacs user for at least 8 years, so I knew how Emacs
behaved in certain circumstances. Then I added this hack. Since
then I didn't notice any bad behavior or difference, except that
I/O become much faster for me. So we have at least one data point
that this kind of approach works and doesn't cause any trouble.
I know that this is a problem for some people, because when I
searched for the cause of this issue, I found multiple reports of
shell being slow in Emacs. The last one happened just several days
ago on reddit:
https://www.reddit.com/r/emacs/comments/17nl7cw/comment/k7tmgz0/?utm_source=share&utm_medium=web2x&context=3
(this reddit comment made me to spend some time investigating the
issue again), explaining the same exact issue I'm having.
But of course, it is possible that this read() loop will cause
trouble for someone. But we're not able to tell this until others
try this out.
^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#44007: 26.3; Strange shell mode performance
2023-11-06 13:37 ` Herman, Géza
2023-11-06 14:40 ` Eli Zaretskii
@ 2023-11-06 22:47 ` Dmitry Gutov
1 sibling, 0 replies; 23+ messages in thread
From: Dmitry Gutov @ 2023-11-06 22:47 UTC (permalink / raw)
To: Herman, Géza, Eli Zaretskii; +Cc: 44007
On 06/11/2023 15:37, Herman@debbugs.gnu.org wrote:
>
> I think it is a bug because Emacs doesn't try to read again if one
> read() was successful. My hacky solution fixes that. With the extra
> cost of one read syscall. But we can do better: we can avoid it if the
> first read call already read 'nbyte' bytes, then there is no need to
> call another read().
FWIW, when I tested different options for bug#66020 (see for example
https://debbugs.gnu.org/66020#58), increasing the default buffer size is
anyway the simplest way to get to top performance without sacrificing
reliability.
There are some patches attached in the subsequent message, BTW, that one
could try out.
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2023-11-06 22:47 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-15 9:53 bug#44007: 26.3; Strange shell mode performance Herman, Géza
2020-10-15 14:10 ` Eli Zaretskii
2020-10-15 14:34 ` Herman, Geza
2020-10-16 8:25 ` Andreas Röhler
2022-01-28 15:26 ` Lars Ingebrigtsen
2022-01-28 22:33 ` Herman, Géza
2022-01-29 6:52 ` Eli Zaretskii
2022-01-29 14:38 ` Lars Ingebrigtsen
2022-01-29 16:10 ` Herman, Géza
2023-11-05 16:46 ` Herman, Géza
2023-11-06 12:08 ` Eli Zaretskii
2023-11-06 12:28 ` Herman, Géza
2023-11-06 13:22 ` Eli Zaretskii
2023-11-06 13:37 ` Herman, Géza
2023-11-06 14:40 ` Eli Zaretskii
2023-11-06 15:00 ` Herman, Géza
2023-11-06 16:52 ` Eli Zaretskii
2023-11-06 17:25 ` Herman, Géza
2023-11-06 22:47 ` Dmitry Gutov
2020-10-16 10:44 ` Herman, Géza
2020-10-16 10:55 ` Eli Zaretskii
2020-10-16 12:23 ` Herman, Géza
2020-10-17 12:48 ` Herman, Géza
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.