分析 Emacs Lisp 行为不当的技巧?

发布于 2024-07-13 12:19:49 字数 339 浏览 9 评论 0原文

我经常定制 Emacs。 最近,我在 .emacs 配置中添加了一些东西,偶尔会将我的 CPU 固定在 100%,但我真的不知道它是什么。

如果我按 Cg 多次,最终我会在迷你缓冲区下方收到一条消息,询问我是否要自动保存文件,然后是否要完全中止 emacs。 如果我一直说“不”并继续按 Cg,最终我可以恢复正常运行 emacs。 大约一个小时后,这种情况会再次发生。

我可以继续像现在这样,注释掉我最近添加的各种内容,重新启动 emacs,试图缩小罪魁祸首的范围,但进展缓慢。

有没有办法可以直接分析 emacs 来找出哪个 lisp 函数占用了 CPU?

I customize Emacs a lot. Recently, I added something to my .emacs configuration that sporadically pegs my CPU at 100%, but I really don't know what it is.

If I press C-g a bunch of times, eventually I'll get a message below the minibuffer asking me if I want to auto save my files and then if I want to abort emacs entirely. If I keep saying no and keeping pressing C-g, eventually I can get back to running emacs as normal. An hour or so later it will happen again.

I could keep going about like I am, commenting out various things I've added recently, restarting emacs, trying to narrow down the culprit, but it's slow going.

Is there a way I can profile emacs directly to figure out what lisp function is hogging the CPU?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蒗幽 2024-07-20 12:19:50

使用 dope.el,您可以分析整个 .emacs 或启动时加载的多个 elisp 文件。 从 www.gnufans.net/~deego/pub/ 下载它emacspub/lisp-mine/dope/

Mx dope-quick-start 将显示一些介绍教程。

编辑:原始 URL 现已失效,但 Git Hub 上有一个工作镜像:
https://raw.github.com/emacsmirror/dope/master/dope。埃尔

With dope.el you can profile entire .emacs or multiple elisp files loaded at startup. Download it from www.gnufans.net/~deego/pub/emacspub/lisp-mine/dope/

M-x dope-quick-start will show a little introduction tutorial.

Edit: The original URL is now defunct, but there is a working mirror on Git Hub:
https://raw.github.com/emacsmirror/dope/master/dope.el

静谧 2024-07-20 12:19:50

严格来说,这不是对您问题的答案,但您可以使用 -q 选项启动 emacs,将 .emacs 加载到使用 Cx Ce 缓冲并评估每个性别,以找出有问题的性别。

This is not, strictly speaking, an answer to your question, but rather than doing the comment-out-and-restart thing, you can start emacs with the -q option, load your .emacs into a buffer and evaluate each sexpr yourself with C-x C-e to track down the offending one.

好菇凉咱不稀罕他 2024-07-20 12:19:49

debug-on-quit 设置为 t 的建议是一个很好的建议,这样您就可以了解 Emacs 正在做什么。 您可以将其视为使用单个样本进行采样分析的一种形式:通常单个样本就足够了。


更新:从版本 24.3 开始,Emacs 包含两个分析器。 profiler.el 中有一个(新的)采样分析器,elp.el 中有一个(旧的)仪器分析器。

采样分析器记录在此处。 使用起来非常简单:

要开始分析,请输入 Mx profiler-start。 您可以选择按处理器使用情况、内存使用情况或两者进行分析。 完成一些工作后,输入 Mx profiler-report 以显示您选择分析的每个资源的摘要缓冲区。 完成分析后,输入 Mx profiler-stop

以下是 Perforce/Emacs 的 cpu+mem 分析器会话的一些示例输出我维护的集成。 我扩展了最顶层的函数 (progn),以便找出 CPU 时间和内存使用来自何处

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%

您可以看到罪魁祸首是 c-after-change,因此看起来我可以通过 inhibit-modification-hooks 本地绑定到此代码周围的 t


您还可以使用 Emacs Lisp Profiler。 这是相当缺乏记录的:您必须阅读 elp.el 中的注释以了解详细信息,但基本上您运行 elp-instrument-package 来打开分析对于具有给定前缀的所有函数,然后使用 elp-results 查看结果。

以下是输入 Mx elp-instrument-package RET c- RET、对 4,000 行 C 进行字体化,然后运行 ​​elp-results(并使用 elp -sort-by-function 按调用计数排序):

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
...

在您的特定情况下,分析器不会立即提供帮助,因为您不知道哪个包有问题。 但是,如果您可以进行猜测(或使用 debug-on-quit 来确定),那么探查器可以帮助您详细诊断问题。

The suggestion of setting debug-on-quit to t so that you can find out what Emacs is up to is a good one. You can think of this as being a form of sampling profiling with a single sample: often a single sample is all you need.


Update: Starting with version 24.3, Emacs contains two profilers. There's a (new) sampling profiler in profiler.el, and an (old) instrumenting profiler in elp.el.

The sampling profiler is documented here. It's pretty straightforward to use:

To begin profiling, type M-x profiler-start. You can choose to profile by processor usage, memory usage, or both. After doing some work, type M-x profiler-report to display a summary buffer for each resource that you chose to profile. When you have finished profiling, type M-x profiler-stop.

Here's some example output from a cpu+mem profiler session with the Perforce/Emacs integration that I maintain. I've expanded the topmost function (progn) in order to find out where the CPU time and memory use is coming 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 the culprit is c-after-change, so it looks as though I could save a lot of CPU time and memory by locally binding inhibit-modification-hooks to t around this code.


You can also use the Emacs Lisp Profiler. This is rather under-documented: you'll have to read the comments in elp.el for the details, but basically you run elp-instrument-package to turn on profiling for all the functions with a given prefix, and then elp-results to see the results.

Here's some typical output after typing M-x elp-instrument-package RET c- RET, fontifying 4,000 lines of C, and then running elp-results (and using elp-sort-by-function to sort by call count):

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 doesn't help immediately, because you don't know which package is at fault. 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.

辞旧 2024-07-20 12:19:49

您是否尝试过:Options->Enter debugger on Quit/Cg? (这是在 emacs22 上)

如果您需要调试 emacs 的启动:使用 emacs -q --no-site-file,访问您的 .emacs (或< code>site-start.el 或其他),激活菜单项 Options->Enter debugger on Quit/Cg,然后激活菜单项 Emacs-Lisp->;当缓冲区出现冻结时,评估缓冲区Cg。 可能有更简单的方法可以做到这一点......

Have you tried: Options->Enter debugger on Quit/C-g? (this is on emacs22)

If you need to debug start-up of emacs: use emacs -q --no-site-file, visit your .emacs (or site-start.el or whatever), activate the menu item Options->Enter debugger on Quit/C-g, and then menu item Emacs-Lisp->Evaluate buffer and C-g when it appears to freeze. There may be a easier way of doing this.........

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文