分析行为不端的 Emacs Lisp 的提示?

Posted

技术标签:

【中文标题】分析行为不端的 Emacs Lisp 的提示?【英文标题】:Tips for profiling misbehaving Emacs Lisp? 【发布时间】:2010-10-08 18:19:33 【问题描述】:

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

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

我可以像我一样继续前进,评论我最近添加的各种内容,重新启动 emacs,试图缩小罪魁祸首,但进展缓慢。

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

【问题讨论】:

【参考方案1】:

debug-on-quit 设置为t 以便您了解Emacs 在做什么的建议是一个不错的建议。您可以将其视为使用单个样本进行抽样分析的一种形式:通常您只需要一个样本。


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

采样分析器是documented here。使用起来非常简单:

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

这是我维护的cpu+mem 分析器会话与Perforce/Emacs integration 的一些示例输出。为了找出where the CPU time and memory use is coming from,我扩展了最顶层的函数(progn)。

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,所以看起来我可以通过locally binding inhibit-modification-hooks to t around this code节省大量的CPU时间和内存。


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

下面是输入M-x elp-instrument-package RET c- RET,字体化4000行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 确定),那么分析器可以帮助您详细诊断问题。

【讨论】:

【参考方案2】:

你试过吗:Options->Enter debugger on Quit/C-g? (这是在 emacs22 上)

如果你需要调试emacs的启动:使用emacs -q --no-site-file,访问你的.emacs(或site-start.el或其他),激活菜单项Options->Enter debugger on Quit/C-g,然后菜单项Emacs-Lisp->Evaluate buffer和@ 987654327@ 当它似乎冻结时。可能有更简单的方法来做到这一点............

【讨论】:

【参考方案3】:

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

M-x dope-quick-start 会展示一个小介绍教程。

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

【讨论】:

感谢您提供的涂料包。使用这个包,我能够重新配置我的 .emacs 以在不到一秒的时间内加载。 :)【参考方案4】:

严格来说,这不是对您问题的回答,而是您可以使用 -q 选项启动 emacs,将您的 .emacs 加载到缓冲区中并评估,而不是执行注释和重新启动的事情每个性别都自己与 Cx Ce 一起追查违规者。

【讨论】:

好点,我一直在做 eval-expression,但我最初并没有想到这种调试模式。 您不想依次评估每个性别(除非您的性别很少)。使用带有 `eval-region' 的二分搜索。

以上是关于分析行为不端的 Emacs Lisp 的提示?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解这个 Common Lisp 包的行为?

请教,关于emacs写lisp自动补全的设置

Emacs Lisp 和 Common Lisp 之间的主要区别是啥? [关闭]

2020-03-01emacs 中使用LISP

用于 Emacs Lisp 的 REPL

lisp编程提示参数太多