Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centaur Tabs causing high CPU on macOS #88

Closed
mexisme opened this issue Feb 24, 2020 · 26 comments
Closed

Centaur Tabs causing high CPU on macOS #88

mexisme opened this issue Feb 24, 2020 · 26 comments

Comments

@mexisme
Copy link

mexisme commented Feb 24, 2020

Using Spacemacs on macOS, I get very high CPU usage when Centaur Tabs is enabled:

  • 75-90% CPU usage (as shown by htop) when running with a GUI
  • CPU usage drops to ~20% in a Terminal.
  • CPU appears to increase when running org-mode.
  • Tried disabling a few features, like
  • Profiling shows that 55% of Emacs' CPU is due to the redisplay_internal function, which seems to be largely due spaceline-ml-main.

I've tried simplifying Spacemacs' theme options, disabling several packages, and it doesn't seem to help much.

By chance, one time I noticed a function with the name "centaur" in it was using a lot of CPU, so I disabled the package, and CPU dropped to below 1% (on average).

I'm not sure how to diagnose this from Emacs, beyond minimal things like running the profiler, and even then I'm not sure what to look at, there.

@tnira
Copy link

tnira commented Feb 24, 2020

I face this problem in same environment.
Reverting to 0383af0 eliminates this problem.

@ema2159
Copy link
Owner

ema2159 commented Feb 25, 2020

That's pretty odd, in fact I've been doing some performance optimizations in order to avoid constant unnecessary recalculations. I would need something more specific like a trace given that I don't have access to any macOS devices.

@ema2159
Copy link
Owner

ema2159 commented Feb 25, 2020

@tnira that's really really odd because the commits after 0383af0 just do two things:

  • The first one adds an idle timer that stops the tabs from recalculating every time the user types or moves the cursor and only recalculates them once after 0.3s of idle time.
  • The second one removes the hook to the buffer-list-update hook which was unnecessary and just was recalculating the tabs each time company created a *temp buffer.

I would like to see if this persists on a non macOS environment, so if any of you have access to another system please check if the problem persists there.

@tnira
Copy link

tnira commented Feb 26, 2020

I did a clean install of ubuntu18 and installed only centaur-tabs with default settings for spacemacs.
CPU usage increases significantly compared to when centaur-tabs is not installed.
However, in the same environment, if you use centaur-tabs with emacs, you will not see a particularly high CPU usage.

@ema2159
Copy link
Owner

ema2159 commented Feb 26, 2020

That's pretty interesting. Spacemacs tends to misbehave from time to time. As far as I know this doesn't happen in Doom. It probably has to do with the timer I added and something inside Spacemacs having conflicts with it. Some information about what function is consuming the time or something like a trace would be really helpful. Maybe using elp to profile certain key functions like centaur-tabs-after-modifying-buffer.

@tnira
Copy link

tnira commented Feb 27, 2020

I'm using Emacs's profiler feature to look for problems in Spacemacs.

The following results were obtained with M-x profiler-report.
スクリーンショット 2020-02-27 12 39 04

In addition, the following results were obtained with M-x elp-instrument-list <RET> cenataur-tabs <RET>.
スクリーンショット 2020-02-27 13 05 17

Going forward, I have no idea what I can do to identify conflicting places in Spacemacs.
I understand this is a phenomenon with Spacemac, but I'd be glad to give me some advice.

@ema2159
Copy link
Owner

ema2159 commented Feb 27, 2020

That Spacemacs profiler report worries me a little bit. I don't quite understand why centaur-tabs-line is called so many times. It shouldn't. As you see the centaur-tabs-after-modifying-buffer is called many times but overall the time it takes is little because it only redisplays the tabs when Emacs is idle, every other time it's basically a boolean evaluation which takes practically no time. Also, another thing that you can do to help me is to do M-x debug-on-entry RET centaur-tabs-line. Hopefully the trace will show us what's triggering the redisplay in Spacemacs.

@sorawee
Copy link

sorawee commented Feb 27, 2020

Just want to confirm that I have this problem too, and after disabling centaur-tabs, the high CPU problem goes away.

@ema2159
Copy link
Owner

ema2159 commented Feb 28, 2020

With the help of the all mighty Doom Emacs owner, I think we have a potential solution to the performance and flickering problems, although I will be able to try it until Sunday because I'm on vacation and I didn't bring my laptop.

hlissner added a commit to doomemacs/doomemacs that referenced this issue Feb 28, 2020
Caused by over-zealous doom-switch-window-hook.

For my own sanity (and if you're curious), I'll break it down here:

1. Doom has a `doom-switch-window-hook` hook. It triggers when window
   focus is changed.
2. We use `buffer-list-update-hook` to trigger
   `doom-switch-window-hook`. (That may sound weird, but this hook is
   reliably executed when window focus is changed -- there are
   safeguards to prevent this from triggering too often)
3. `buffer-list-update-hook` triggers whenever a buffer is created, but
   `doom-switch-window-hook` only triggers if the created buffer is in
   a new window.
4. The use of `with-temp-buffer` in `centaur-tabs-line-format` counts as
   "buffer creation" in a "new window".
5. `+vc-gutter-update-h` is in `doom-switch-window-hook`. This refreshes
   git-gutter, which initiates a redraw of Emacs.
6. When Emacs redraws, it recalculates its mode and header lines. which
   triggers `doom-switch-window-hook` once, which triggers
   `+vc-gutter-update-h`, which redraws the screen, then Emacs recalculates
   the header line, running `centaur-tabs-line-format`...

Infinite loop ensues

Hopefully fixes:
- #2436
- ema2159/centaur-tabs#18
- ema2159/centaur-tabs#88
daveduthie pushed a commit to daveduthie/doom-emacs that referenced this issue Feb 28, 2020
Caused by over-zealous doom-switch-window-hook.

For my own sanity (and if you're curious), I'll break it down here:

1. Doom has a `doom-switch-window-hook` hook. It triggers when window
   focus is changed.
2. We use `buffer-list-update-hook` to trigger
   `doom-switch-window-hook`. (That may sound weird, but this hook is
   reliably executed when window focus is changed -- there are
   safeguards to prevent this from triggering too often)
3. `buffer-list-update-hook` triggers whenever a buffer is created, but
   `doom-switch-window-hook` only triggers if the created buffer is in
   a new window.
4. The use of `with-temp-buffer` in `centaur-tabs-line-format` counts as
   "buffer creation" in a "new window".
5. `+vc-gutter-update-h` is in `doom-switch-window-hook`. This refreshes
   git-gutter, which initiates a redraw of Emacs.
6. When Emacs redraws, it recalculates its mode and header lines. which
   triggers `doom-switch-window-hook` once, which triggers
   `+vc-gutter-update-h`, which redraws the screen, then Emacs recalculates
   the header line, running `centaur-tabs-line-format`...

Infinite loop ensues

Hopefully fixes:
- doomemacs#2436
- ema2159/centaur-tabs#18
- ema2159/centaur-tabs#88
@ema2159 ema2159 closed this as completed in c3254ef Mar 1, 2020
@ema2159
Copy link
Owner

ema2159 commented Mar 1, 2020

Done! It should be fixed now.

@sorawee
Copy link

sorawee commented Mar 2, 2020

Hmm. It's still not fixed for me unfortunately. I made sure that my centaur-tabs.el has (let (buffer-list-update-hook) before (with-temp-buffer (that is, it is indeed up-to-date).

@ema2159
Copy link
Owner

ema2159 commented Mar 2, 2020

@sorawee could you show me a screenshot from the profiler?

@sorawee
Copy link

sorawee commented Mar 2, 2020

Here it is:

Screen Shot 2020-03-01 at 19 24 14

@sorawee
Copy link

sorawee commented Mar 2, 2020

Note that if I revert the changes in 3658efc, the issue goes away.

@ema2159
Copy link
Owner

ema2159 commented Mar 2, 2020

@sorawee are you sure that you updated the package correctly?
image
That's my profiler report, and 3658efc shouldn't trigger any unnecessary recalculations (unless Spacemacs has some weird issues with timers, which I doubt).
@tnira @mexisme, could you do some profiling just to see if this also happens to you?

@ema2159 ema2159 reopened this Mar 2, 2020
@tnira
Copy link

tnira commented Mar 2, 2020

I immediately started using the latest version.
As far as I have tried, this fix does not lead to lower CPU utilization.
スクリーンショット 2020-03-02 13 45 58

I try to isolate the problem as much as possible, but I haven't done that yet.

@sorawee
Copy link

sorawee commented Mar 2, 2020

I tried to debug-on-entry on centaur-tabs-line, but it seems to have no effect. The tutorial of debug-on-entry seems to suggest that we need to "invoke" it somehow, but I guess because it's already running, the newly instrumented version is not invoked?

Another thing I'm curious is, for c3254ef, you add (let (buffer-list-update-hook) ...) to the code. What does that do? I've personally never seen this form of let before. Thought that let must following by a list of binding pairs?

@ema2159
Copy link
Owner

ema2159 commented Mar 2, 2020

@sorawee. I'm not quite sure, that's what Henrik (Doom maintainer) advised me to do. He explains some details here: daveduthie/doom-emacs@73f29cc.
However, you mentioned that removing the timer (changes from 3658efc) does have a positive impact. @tnira can you confirm this?

@xml-js-dev
Copy link

I can confirm this issue on Ubuntu 18.04, using Emacs 27 on release tip (not spacemacs). Profiler shows a total of 50% CPU usage from Centaur tabs during light editing (e.g. commenting-out lines). I'm using the icons integration with centaur tabs, but otherwise it's stock. As soon as I disable centaur tabs, Emacs is smooth as butter.

@sorawee
Copy link

sorawee commented Mar 2, 2020

Another thing I'm curious is, for c3254ef, you add (let (buffer-list-update-hook) ...) to the code. What does that do? I've personally never seen this form of let before. Thought that let must following by a list of binding pairs?

Just to answer my own question. In elisp, this form of let means declare buffer-list-update-hook, but don't assign it any value (from https://stackoverflow.com/a/32802503/718349). I fail to see how this would solve the problem, though...

@ema2159
Copy link
Owner

ema2159 commented Mar 2, 2020

@sorawee now I understand. The problem was that the (with-temp-buffer... function although it only creates a temporal buffer, it triggers the buffer-list-update-hook which triggers a lot of functions and also unnecessarily redisplays the tabs indefinitely. Wrapping the (with-temp-buffer... with that let statement "empties" the buffer-list-update-hook inside the scope of that let statement, so when (with-temp-buffer... triggers the hook, it doesn't execute any functions.

GTrunSec pushed a commit to GTrunSec/doom-emacs that referenced this issue Mar 3, 2020
Caused by over-zealous doom-switch-window-hook.

For my own sanity (and if you're curious), I'll break it down here:

1. Doom has a `doom-switch-window-hook` hook. It triggers when window
   focus is changed.
2. We use `buffer-list-update-hook` to trigger
   `doom-switch-window-hook`. (That may sound weird, but this hook is
   reliably executed when window focus is changed -- there are
   safeguards to prevent this from triggering too often)
3. `buffer-list-update-hook` triggers whenever a buffer is created, but
   `doom-switch-window-hook` only triggers if the created buffer is in
   a new window.
4. The use of `with-temp-buffer` in `centaur-tabs-line-format` counts as
   "buffer creation" in a "new window".
5. `+vc-gutter-update-h` is in `doom-switch-window-hook`. This refreshes
   git-gutter, which initiates a redraw of Emacs.
6. When Emacs redraws, it recalculates its mode and header lines. which
   triggers `doom-switch-window-hook` once, which triggers
   `+vc-gutter-update-h`, which redraws the screen, then Emacs recalculates
   the header line, running `centaur-tabs-line-format`...

Infinite loop ensues

Hopefully fixes:
- doomemacs#2436
- ema2159/centaur-tabs#18
- ema2159/centaur-tabs#88
@ema2159
Copy link
Owner

ema2159 commented Mar 6, 2020

@sorawee @mexisme @tnira @xml-js-dev how about now?

@sorawee
Copy link

sorawee commented Mar 6, 2020

It's fixed! Thank you :)

@ema2159
Copy link
Owner

ema2159 commented Mar 6, 2020

Finally! Thanks!!!!

@ema2159 ema2159 closed this as completed Mar 6, 2020
@sorawee
Copy link

sorawee commented Mar 24, 2020

A quick note: while it's finally not taking 90% CPU usage, it's still taking about 30%. While this is totally manageable for me, it might suggest that there's a lurking bug somewhere...

@AlessandroW
Copy link

I have the same issue here:
image
Using (package! centaur-tabs :pin "5453317b6b9f68bfbd934eee3b883207bfa331e0")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants