unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).