The suggestion of setting up debug-on-quit to t so that you can find out what Emacs is is good. You can think of it as a form of profiling a sample using one sample: often you only need one sample.
Update: Starting with version 24.3, Emacs contains two profilers. profiler.el has a (new) sampler and an (old) tool profiler in elp.el
The sampling profiler is described here . It is pretty simple:
To start profiling, type Mx profiler-start . You can choose the profile used by the processor, memory usage, or both. After doing some work, enter Mx profiler-report to display a summary buffer for each resource that you selected for the profile. When profiling is complete, enter Mx profiler-stop .
Here is an example from the output of cpu+mem profiler with the Perforce / Emacs integration that I support. I expanded the topmost function ( progn ) to find out where the processor time and memory usage come from .
Function Bytes % - progn 26,715,850 29% - let 26,715,850 29% - while 26,715,850 29% - let 26,715,850 29% - cond 26,715,850 29% - insert 26,715,850 29% + c-after-change 26,713,770 29% + p4-file-revision-annotate-links 2,080 0% + let 20,431,797 22% + call-interactively 12,767,261 14% + save-current-buffer 10,005,836 11% + while 8,337,166 9% + p4-annotate-internal 5,964,974 6% + p4-annotate 2,821,034 3% + let* 2,089,810 2%
You can see that c-after-change culprit, so it seems to me that I can save a lot of time and processor memory by locally binding inhibit-modification-hooks up to t around this code .
You can also use Profiler Emacs Lisp. This is rather not documented enough: you will need to read the comments in elp.el for details, but basically you run elp-instrument-package to enable profiling for all functions with a given prefix, and then elp-results to see the results.
Here is a typical output after entering Mx elp-instrument-package RET c- RET , shading 4000 C lines, and then running elp-results (and using elp-sort-by-function to sort by the number of calls):
Function Name Call Count Elapsed Time Average Time ============================= ========== ============ ============ c-skip-comments-and-strings 107 0.0 0.0 c-valid-offset 78 0.0 0.0 c-set-offset 68 0.031 0.0004558823 c-end-of-macro 52 0.0 0.0 c-neutralize-CPP-line 52 0.0 0.0 c-font-lock-invalid-string 20 0.0 0.0 c-set-style-1 19 0.031 0.0016315789 ...
In your particular case, the profiler does not help immediately, because you do not know which package is faulty. But if you can make a guess (or use debug-on-quit to find it for sure), then the profiler can help you diagnose the problem in detail.