Subject: Re: bug#73046: 29.4; Emacs 100% CPU usage for several seconds when opening dired buffer over TRAMP

From: Michael Albinus <[email-masked]>
Date: Fri, 20 Sep 2024 11:54:28 +0200

Eli Zaretskii <[email-masked]> writes:

Hi,

> If 3 surprised you, then the reason is simple: sit-for returns
> immediately if any input is available, so typing effectively disables
> the wait.  This could be countermanded by unconditional sleep, but
> AFAIU Michael is rethinking the whole issue, so we should wait for him
> to reach his conclusions.
>
> In any case, interrupting the wait when you type makes sense in
> general: it means Emacs is expected to respond sooner, which in most
> cases indeed means to stop waiting immediately.

I played with the different configurations to use sit-for. The test
scenario is simple and can be reproduced with any remote connection, be
it slow or fast:

--8<---------------cut here---------------start------------->8---
emacs -Q /ssh:remotehost:
M-! sleep 30
--8<---------------cut here---------------end--------------->8---

This starts a synchronous remote shell-command, and Tramp must wait for
the response in order to return the exit code (akways 9 in this
scenario). Observe the Emacs resource consumption by 'top' in another shell.

As a second test, I use the Tramp test suite in order to see whether
there is performance degradation. It is sufficient to run the test cases
tramp-test11-copy-file and tramp-test12-rename-file.

make -C test tramp-tests SELECTOR='"11\\|12"'

1. No sit-for call at all, as it has been the case when Suhail reported
the problem.

Emacs consumes 99% .. 100% CPU. The test suite reports

--8<---------------cut here---------------start------------->8---
   passed  1/2  tramp-test11-copy-file (1.645027 sec)
   passed  2/2  tramp-test12-rename-file (2.172439 sec)
--8<---------------cut here---------------end--------------->8---

2. Use (sit-for 0.005) in `tramp-wait-for-regexp', as done initially
with my patch.

Emacs consumes 42% .. 47% CPU. Good. However, the test suite reports

--8<---------------cut here---------------start------------->8---
   passed  1/2  tramp-test11-copy-file (5.311830 sec)
   passed  2/2  tramp-test12-rename-file (4.451581 sec)
--8<---------------cut here---------------end--------------->8---

This is a serious performance degradation, which isn't acceptable I
believe.

3. Use (sit-for 0.00005) in `tramp-wait-for-regexp', a much shorter timeout.

Emacs consumes 72% .. 74% CPU. Not ideal, but better than 100%. The test suite reports

--8<---------------cut here---------------start------------->8---
   passed  1/2  tramp-test11-copy-file (1.643277 sec)
   passed  2/2  tramp-test12-rename-file (1.800990 sec)
--8<---------------cut here---------------end--------------->8---

This is comparable to the initial values (there's always a small
difference).

4. Use (sit-for 0) in `tramp-wait-for-regexp'.

Emacs consumes 72% .. 74% CPU, the same as in 3. The test suite reports

--8<---------------cut here---------------start------------->8---
   passed  1/2  tramp-test11-copy-file (1.562353 sec)
   passed  2/2  tramp-test12-rename-file (1.626922 sec)
--8<---------------cut here---------------end--------------->8---

Seems to be the best compromise, I'm in the mood to apply.

Comments?

Best regards, Michael.