lastquestion / explain-pause-mode

top, but for Emacs.
GNU General Public License v3.0
239 stars 6 forks source link

Long Emacs session statistics #29

Open yantar92 opened 4 years ago

yantar92 commented 4 years ago

Apart from some commands taking a lot of time/memory to run, there is another common problem of Emacs being slower when running for a long time. The same command running on fresh Emacs and Emacs running for several days may take several times longer to finish.

The slowdown can be caused by many reasons, like overall memory leakage or just changing the environment (e.g. changing buffer text or buffer-local variables). Tracking down this kind of problems is extremely difficult without a right toolset. There were some attempts to make a toolset in the past [1,2], but they are often troublesome to use.

If would be useful to track how cpu time/memory consumption changes through Emacs session for various commands.

[1] https://www.emacswiki.org/emacs/EmacsMemoryDebugging [2] http://notes.secretsauce.net/notes/2015/10/05_memory-leak-debugging-tools.html

lastquestion commented 4 years ago

If you try explain-pause-top right now, and keep the buffer open (you can bury it), it will collect statistics and show them to you for all commands. Your use case should be solved by this, once a couple of features are implemented, some of which are easier and some harder:

  1. I was already thinking about trees in the original PR #4 . Currently, say self-insert-command is collapsed for all buffers, and averaged for all invocations. But this isn't useful sometimes: it might be slow in one buffer or fast in another. I am thinking of rooting every command with the buffer it originated into (minibuffer commands already work like this). Then, the top would normally summarize all self-insert-command (or indent-*... etc etc) into one row, but allow expansion to see the actual buffers that were slow or fast. This should allow you to notice "oh hey xyz is slower 5 hours later but only in this buffer, HM!"

  2. Currently, it only collects data so long the buffer is open. When it's closed, data collection is paused, but the data is not cleared, so that's a bit of a problem. Also, you can't actually reset the data, that needs a keymap entry and an interactive command.

  3. Finally, the UI there should allow you to select (target) a command for profiling. It should also have a face to show you that one is slow(er).

Probably, with the combination of these three, plus some way of "freezing" a explain-pause-top buffer to compare, this would allow you to see what is going on. You can copy and paste the buffer - it's emacs, obvious - but it'd be nice to be able to freeze it via a command, too.

yantar92 commented 4 years ago
  1. I was already thinking about trees in the original PR #4 . Currently, say self-insert-command is collapsed for all buffers, and averaged for all invocations. But this isn't useful sometimes: it might be slow in one buffer or fast in another.

Sure. For example, line movement commands can be extremely slow in org buffers in particular (because of large number of overlays).

  1. Currently, it only collects data so long the buffer is open. When it's closed, data collection is paused, but the data is not cleared, so that's a bit of a problem.

Averaging over the whole Emacs session is not helpful to see how the speed degrades during runtime. What would probably be more useful is some way to visualize the command performance vs. Emacs runtime. Or even provide memory usage, current buffer, buffer-local memory usage, and cpu load alongside with the information about each command invokation. If not visualization, a way to export all (or at least some) of the additional info would be helpful to analyze Emacs performance issues.