为什么 emacs 给出提示的速度很慢

  • 本文关键字:速度 提示 emacs emacs
  • 更新时间 :
  • 英文 :


如果我删除.emacs文件和.emacs.d文件夹,只是为了确保我观察到的不是由我个人配置中的问题引起的,并且我调用emacs foo.txtemacs 窗口打开,使用"Lisp Interaction ElDoc"保持空白至少 5 秒 写在底部栏的中心,通常指示主要模式。然后(即几秒钟后),窗口垂直分成两部分,启动画面在底部,文档foo.txt在顶部,"Lisp Interaction ElDoc"被替换为"(文本)"。

如果我随后关闭文档并立即调用emacs foo.txt再次,然后我直接获得最后一个窗口(一分为二,带有初始屏幕和所有内容),而不会卡在第一个状态几秒钟。

但是,如果我关闭文档并等待一段时间(一分钟左右),然后调用emacs foo.txt同样,Emacs 窗口打开,它保持空白至少 5 秒钟,底部栏中央写着"(基本)",消息"正在加载/usr/share/emacs/site-lisp/site-start.d/rpmdev-init.el...done'(这是从/usr/share/emacs/site-lisp/site-start.d/加载的最后一个文件,如果你想知道的话)。然后,文件与初始屏幕等一起弹出。

*Messages*的内容没有给我任何关于 emacs 在完成加载rpmdev-init.el和显示初始屏幕之间可以尝试做什么的信息(带有消息"有关 GNU Emacs 和 GNU 系统的信息,请键入 C-h C-a")。以下是*Messages*的内容:

Loading /usr/share/emacs/site-lisp/site-start.d/auctex.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/autoconf-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/clang-format.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/clang-include-fixer.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/clang-rename.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/cmake-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/desktop-entry-mode-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/mercurial-site-start.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/pg-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/preview-latex.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/protobuf-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/rpmdev-init.el (source)...done
For information about GNU Emacs and the GNU system, type C-h C-a.

这种行为(有时必须等待几秒钟才能编辑文件)很烦人。我知道我可以将 emacs 作为服务器启动,以避免每次我想打开 emacs 窗口时重新加载所有内容,但尽管如此,我想了解幕后发生的事情,因为这似乎是异常的痕迹。所以我的问题是:有没有人知道是什么原因导致 emacs 有这种行为?或者关于如何继续弄清楚的任何线索?

我尝试了emacs -qemacs -Q,并观察到了相同的现象。我在 Fedora 34 上使用 emacs 27.2。

编辑:类似的问题经常发布在StackOverflow上(据我所知,SO上的问题比任何其他StackExchange网站上都要多)。例如:

  • 发现的最接近我的问题的问题在这里。
  • 另一个非常接近的在这里(或这里只是一个重复)。
  • 那个。
  • 那个和那个似乎与我的情况无关。
  • 等。

通常的嫌疑人是错误的配置(此处排除,因为即使使用-Q也会出现问题)或错误的主机名配置(据我所知,应该在现代版本的 emacs 上修复,无论如何,我的主机名配置正确)。

我仍在尝试比较emacs_slow.straceemacs_fast.strace

获得的痕迹
strace -tt -o emacs_slow.strace emacs foo.txt -eval '(kill-emacs)' &&  
strace -tt -o emacs_fast.strace emacs foo.txt -eval '(kill-emacs)'

它们都是大约 21k 行并且非常相似。如果有人知道要具体检查什么,欢迎提供建议。

我终于找到了问题的原因。事实证明,它针对我的个人情况相当具体,但我在这里发布答案而不是删除问题,因为:

  1. 事实证明,我的问题确实与StackOverflow上发出信号并列在我的帖子中的所有其他类似问题不同。
  2. 我设法诊断问题的方式对其他人很有用(它确实是作为解决方案的一部分提出的,也是对上述两个问题的评论)。
  3. 尽管它
  4. 相当具体,但我不是第一个遇到它的人,因为我终于找到了有相同问题的人(尽管他们没有通过相同的症状识别它),并且我成功地应用了他们的修复程序。

多亏了strace,我真的明白发生了什么.当 emacs 加载缓慢时获得的跟踪与加载速度快时的跟踪非常相似,只是在此调用时

faccessat2(AT_FDCWD, "/run/netsop/u/_MTN/format", F_OK, AT_EACCESS) = -1 ENOENT (No such file or directory)

慢跑在继续之前等待 8 秒,而快跑立即继续。

/run/netsop/u/是一个网络挂载点,其子文件夹会根据需要自动挂载(并在一段时间后自动卸载),所以发生的事情变得很清楚:Emacs 试图查看文件/run/netsop/u/_MTN/format是否存在,只是为了得到这个答案,它触发了文件夹的挂载(这恰好需要或多或少的 8 秒)。当 emacs 在挂载点还在时再次启动时,它会立即得到答案。

一旦我知道问题的原因是emacs试图查看_MTN/format是否存在,我就用谷歌搜索它并找到了上面提到的修复程序,这只是添加

(setq vc-handled-backends nil)

.emacs中,为了禁用 emacs 的版本控制能力。

当然,更好的解决方法是保留 vc 句柄后端,例如,向 emacs 指定一个文件夹列表,它不应该在其中查找版本控制配置文件,但我不知道这样的解决方案。

是这个吗?

*** GNU/Linux: slow startup on Linux-based GNU systems.
People using systems based on the Linux kernel sometimes report that
startup takes 10 to 15 seconds longer than 'usual'.
This is because Emacs looks up the host name when it starts.
Normally, this takes negligible time; the extra delay is due to
improper system configuration.  This problem can occur for both
networked and non-networked machines.
Here is how to fix the configuration.  It requires being root.
**** Networked Case.
First, make sure the files '/etc/hosts' and '/etc/host.conf' both
exist.  The first line in the '/etc/hosts' file should look like this
(replace HOSTNAME with your host name):
127.0.0.1      HOSTNAME
Also make sure that the '/etc/host.conf' files contains the following
lines:
order hosts, bind
multi on
Any changes, permanent and temporary, to the host name should be
indicated in the '/etc/hosts' file, since it acts a limited local
database of addresses and names (e.g., some SLIP connections
dynamically allocate ip addresses).
**** Non-Networked Case.
The solution described in the networked case applies here as well.
However, if you never intend to network your machine, you can use a
simpler solution: create an empty '/etc/host.conf' file.  The command
'touch /etc/host.conf' suffices to create the file.  The '/etc/hosts'
file is not necessary with this approach.

引自 PROBLEMS 文件;键入C-hC-p

最新更新