【问题标题】:How can I make Emacs start-up faster?如何让 Emacs 启动更快?
【发布时间】:2010-10-21 04:37:39
【问题描述】:

我使用Emacs v. 22(控制台版本,远程使用PuTTY 或本地使用Konsole)作为我在Linux 上的主要文本编辑器。每次我启动它都需要一段时间来加载,可能差不多一秒钟,虽然我从来没有计时过。我经常打开和关闭 Emacs,因为我更习惯使用 Bash 命令行进行文件/目录操作和编译。

如何加快启动时间?

【问题讨论】:

  • 我在 Ubuntu 上遇到了同样的问题。似乎有很多 Emacs 包在启动时通过默认包配置自动加载,我不知道如何阻止我不想要/不需要的包。
  • @Chris,尝试使用 --no-site-file 来查看 Emacs,可能是安装中加载了不需要的软件包。
  • 我们通过删除在客户端和服务器之间来回发送的一些颜色信息,大大减少了我工作的 emacs 的加载时间(加载时间减少了约 80%)。
  • 配置您的 .emacs。我在下面的答案中发布了一个链接,解释了如何做到这一点。
  • 您不必完全关闭 Emacs,只需键入 C-z 即可暂停它。然后,在 bash 中,键入命令 fg 以在前台继续它。除此之外,请尝试在 Emacs 中使用 M-x term 在 emacs 中创建一个 shell(在您的 shell 中:-))。这样,您实际上不必离开 Emacs,您只需在缓冲区中有另一个 bash shell 可用。

标签: emacs performance


【解决方案1】:

其他人已经使用 gnuserveemacsclient 进行了介绍,我建议在 emacs 中编译(能够跳转到编译错误是一个胜利)。

但是,可以通过以下方式加速 .emacs:

  1. 字节编译.emacs文件,可以使用this snippet of code自动完成

  2. autoloaded 功能替换尽可能多的(require 'package) 语句。这将延迟 lisp 的加载,直到实际需要它。使用这种技术,我可以将我的启动速度从 >6 秒加快到 autoload。

  3. 删除不再使用的代码/功能。

  4. 尝试使用选项--no-site-file 运行emacs,以避免在站点安装site-start.el 中加载不必要的包。

  5. 如果你真的很认真,你可以使用已经加载的你最喜欢的功能来滚动你自己的 emacs。当然,这意味着对 .emacs 中的内容进行更改会更复杂,因为它是二进制文件的一部分。点击链接了解如何使用dump-emacs

  6. 购买速度更快的计算机和/或速度更快的磁盘。

如何确定 .emacs 加载的内容

现在,您如何找出 .emacs 加载的内容?目标是删除功能,还是延迟它?检查您的 *Messages* 缓冲区,其中包含以下行:

正在加载 /home/tjackson/.emacs.tjackson.el(来源)... 正在加载/home/tjackson/installed/emacs/lisp/loaddefs.el(源代码)...完成 正在加载 /user/tjackson/.elisp/source/loaddefs.el (source)...完成 加载自动恢复...完成 正在加载 /home/tjackson/.emacs.tjackson.el(来源)...完成

如果您注意到,Loading 语句可以嵌套:第一个.emacs.tjackson.el... 结尾,最后一行显示.emacs.tjackson.el 加载为...done。所有其他文件都是从我的.emacs.tjackson.el 文件中加载的。所有其他负载都是原子的。

注意:如果你有一个大的 .emacs,*Messages* 缓冲区可能会丢失一些消息,因为它只保留固定数量的信息.您可以尽早将此设置添加到您的 .emacs 以保留所有消息:

(setq message-log-max t)

注意:如果nomessage 的第四个参数nomessage 不为零,则'load 命令将禁止显示消息,因此请删除任何此类调用(或者,建议'load 并强制执行第四个参数)参数为nil)。

【讨论】:

  • 您能否详细说明第二个建议?我不明白如何用自动加载替换我的需求调用,因为自动加载似乎需要一个文档字符串参数。
  • @Micha90 好吧,单击autoload 的链接以获取完整的详细信息,但如果您不能(或不想)修改源代码以插入;;;###autoload 行,您可以在 .emacs 中手动添加像 (autoload 'tcl-mode "tcl-mode") 这样的行以启用自动加载(在这种情况下为 tcl-mode)。
【解决方案2】:

除了Adam Rosenfield's solution,我推荐使用Emacs in server mode。您可以将(server-start) 添加到您的dotmacs 中,并在您想在Emacs 中打开文件时运行emacsclient 而不是emacs。这样你只需支付一次 Emacs 的加载费用,然后客户端立即弹出。

编辑

你说得对,v22 不会创建新框架。创建一个可以解决问题的 shell 脚本:

#!/bin/bash
# Argument: filename to open in new Emacs frame
/usr/bin/emacsclient -e '(let ((default-directory "`pwd`/")) (select-frame (make-frame)) (find-file "'$1'"))'

编辑 2

在 v24+ 中,您可以使用emacsclient -c 来创建新框架。

【讨论】:

  • 我正在为这个解决方案苦苦挣扎 - 我已经启动了服务器,但我似乎无法让 emacsclient 开始一个新框架。显然我的 emacs 版本不支持“-c”或“-t”选项。有什么建议吗?
  • emacs --daemon 仅在 v23 及更高版本中受支持。另外,如果它发现您的 ~/.emacs 有错误,它可能会在您第一次移动到这个新版本时发现它不会正确启动:)
  • 如果您在服务器模式下运行 emacs,这是一种相当快的方式。这些快捷方式可能会派上用场.... 1. 启动服务器emacs --daemon 这将导致它运行服务器并将控制权返回给终端。 2.然后编辑文件。 emacsclient <filename> 3. 停止守护进程emacsclient -e "(kill-emacs)"
  • 我遇到以下错误:*ERROR*: Unknown terminal type
  • @alper 看看这是否有帮助:unix.stackexchange.com/questions/119871/…
【解决方案3】:

不要在每次要使用 shell 时关闭 Emacs。使用 Ctrl-Z 将 Emacs 移至后台,并在 Bash 中使用 fg 命令将其移回前台。

【讨论】:

  • +1 很好的尝试来避免这个问题。您可以在答案中添加启动另一个 putty 会话和/或运行 screen。 Chris Conway 的M-x shell 回答也是本着这种精神。
  • 将链接更正为官方自动加载链接:它是gnu.org/software/emacs/manual/html_node/elisp/Autoload.html
  • 从未想过!我一定会试试的! (y)
【解决方案4】:

几个提示:

  1. 使用自动加载

    使用自动加载可以避免加载库,直到您使用它们。 例如:

    (if (locate-library "ediff-trees")
        (autoload 'ediff-trees "ediff-trees" "Start an tree ediff" t))
    
  2. 编译你的 .emacs

    虽然有陷阱,但会稍微提高你的速度 使用版本控制并且您的 .emacs 比 .emacs.elc 更新。 一个常见的技巧是:

    (defun autocompile nil
      "compile itself if ~/.emacs"
      (interactive)
      (require 'bytecomp)
      (let ((dotemacs (file-truename user-init-file)))
        (if (string= (buffer-file-name) (file-chase-links dotemacs))
          (byte-compile-file dotemacs))))
    
    (add-hook 'after-save-hook 'autocompile)
    
  3. 学会爱上 emacs 服务器。

    将 emacs 作为服务器运行意味着永远不必关闭它。然而 我注意到您仍在使用 emacs22。 emacs23 支持多 tty,这使得 在一个屏幕会话中运行 emacs 然后启动要容易得多 另一个终端的新窗口。我使用 emacs 为我的邮件编辑邮件 client (mutt) 和 emacsclient 非常适合这种快速编辑。

【讨论】:

    【解决方案5】:

    其中一个

    M-x shell
    M-x eshell
    M-x term
    M-x ansi-term
    

    应该满足您在 Emacs 中的命令行需求。

    您也可以使用M-!(又名M-x shell-command)来执行单行,而不会掉入shell。

    【讨论】:

      【解决方案6】:

      检查您的.emacs 文件,看看您是否加载了不必要的包。加载包可能需要大量时间。例如,如果您正在编辑 PHP 文件,您可能只想加载 php-mode 包。你可以通过安装一个钩子程序来做到这一点,虽然我不确定细节。

      还要确保您正在加载的所有包都已编译(.elc 文件)。您可以通过运行编译elisp 文件

      emacs -batch -f batch-byte-compile thefile.el
      

      已编译的包加载速度比未编译的包快得多。

      【讨论】:

        【解决方案7】:

        “我经常打开和关闭 emacs,因为我更习惯使用 bash 命令行进行文件/目录操作和编译。”

        您正在描述像 vim 这样的编辑器的使用方式。拍摄进出。 Emacs 通常保持打开状态,并且大部分都是从“内部”完成的。 hiena 已经在这里回答了正确的方法。

        【讨论】:

        • 你可以用 C-z 挂起它,而不是退出 emacs,然后用 fg 唤醒它……
        • @Damien Pollet - (困惑),...嗯,是的,我知道这一点。我不想重复已经说过的话,所以我只是指着 hiena 的帖子。
        【解决方案8】:

        最快的方法是profile your .emacs。在我发现 .emacs 中的 4 个特定行占用了超过 80% 的加载时间后,我在 5 分钟内将加载时间从 >3 秒缩短到 1 秒。

        【讨论】:

        • profile-dotemacs 包似乎没有得到积极维护(此答案中链接的 Emacswiki 页面的“下载”部分指的是存档的互联网页面)。相反,Emacs Start Up Profiler (ESUP) 似乎更新了。
        【解决方案9】:

        除了autoload(正如其他人所建议的那样)之外,帮助我减少.emacs 加载时间的一件事是eval-after-load。在以下示例中,延迟对 sql-set-product 的调用使您不必在 .emacs 中加载 sql,从而使现有的 sql 自动加载更有效。

        (加载后评估“sql” '(预测 (sql-set-product 'mysql) (setq sql-mysql-options '("-C" "-t" "-f" "-n")) (setq sql-sqlite-program "sqlite3") ))

        当然,对于某些软件包,会有hook 可用,您可以做同样的事情,但有时没有,否则这种方式更容易考虑。

        【讨论】:

        • 使用eval-after-load 的一个缺点是它会阻止对代码进行编译时检查,这在自定义变得复杂时非常有用。对于这种情况,我的标准方法是例如(eval-after-load "org" (require 'my-org-customization)),即将定制移动到一个单独的(编译的)文件中。
        【解决方案10】:

        Emacs 被设计为“一直”运行(或至少长时间运行),因此不建议在一天中多次启动和停止 Emacs。

        我建议使用屏幕。 Screen是一个终端多路复用器,在一个终端中为您提供无限的虚拟终端。

        安装后,只需在终端中写入“screen emacs”即可。 Emacs 将照常启动,但按“c-a c”(即按 ctrl-a 然后按 c)将打开一个新的虚拟终端。您可以通过按“c-a c-a”(即两次 ctrl-a)返回 emacs。

        您甚至可以从正在运行的屏幕会话中分离,键序列是“c-a d”。

        通过发出“screen -R”重新附加到会话,您将回到您离开的地方。这使您能够在工作中启动 emacs 会话、分离、回家和在家重新连接。

        我已经连续几个月像这样运行 Emacs。

        这是官方网站:http://www.gnu.org/software/screen/,但请尝试使用谷歌搜索屏幕教程和操作方法

        【讨论】:

          【解决方案11】:

          您可以使用benchmark-init 来分析您的 Emacs 启动。它将跟踪正在加载哪些模块以及每个模块花费了多少时间。结果可以以表格或树的形式呈现。树可以更轻松地跟踪谁加载了什么,这在您加载具有大量依赖项的包时会很有帮助,并且表格形式可以帮助您快速找到大部分时间都花在了哪里。

          获得这些结果后,请尝试确定是否必须始终加载所有模块,或者是否可以按需加载其中一些模块。例如,在我的配置中,我只加载特定于某些模式的 Emacs 扩展,当该模式实际激活时,因为大多数时候我只在会话中使用它们的一小部分。 eval-after-load 和模式挂钩将成为您的朋友。

          通过应用这种方法我的 Emacs 会在 3-4 秒内启动,并且我已经安装了近 200 个扩展。大部分时间都花在加载 Helm 上,我总是加载它,因为它替换了始终需要的查找文件和其他核心功能,还有 CEDET,因为我使用的是最新版本,并且必须在 Emacs 尝试加载旧版本之前加载它内置版本。

          【讨论】:

            【解决方案12】:

            其他人没有提到的一件事是包含您使用的 elisp 库作为dumped Emacs 的一部分,以将库加载时间从 Emacs 启动转移到 Emacs 构建。它不适合胆小的人,但如果您在 .emacs 中加载多个库,它可能会为您赢得几秒钟的启动时间。

            【讨论】:

              【解决方案13】:

              尝试使用https://github.com/jwiegley/use-package 宏来定义您的包加载和自定义。它为您处理包的延迟加载,即使在存在大量已配置包的情况下,也相对容易获得良好的启动时间。我的 .emacs 中引用了近 100 个包,但我的启动时间在 Linux 上不到 2 秒,在 Mac 上不到 2.2 秒。

              【讨论】:

                【解决方案14】:

                我有大约 120 秒的开始时间。我能够找到安装此的修复程序:

                https://github.com/dholm/benchmark-init-el 放在你的 init.el

                (let ((benchmark-init.el "~/.emacs.d/el-get/benchmark-init/benchmark-init.el"))
                  (when (file-exists-p benchmark-init.el)
                    (load benchmark-init.el)))
                

                然后,一旦你的 emacs 启动,运行:

                M-x benchmark-init/show-durations-tree

                在我这边,问题是 tramp-loaddefs 中的 127 秒

                我通过添加修复它

                127.0.0.1  host.does.not.exist
                

                /etc/hosts 这让我的启动速度很快

                在此处查看更多信息:https://github.com/emacs-helm/helm/issues/1045

                另一件事可能对您有帮助:https://www.emacswiki.org/emacs/ProfileDotEmacs

                【讨论】:

                • 你拯救了我的理智。因此,我的初始化文件大约需要 2 分钟。谢谢!
                【解决方案15】:

                这不能回答问题,但有点相关

                我不知道如何让它启动得更快,但我可以建议以下几点:

                • 对于您在命令行上执行的大多数操作,您可以在 emacs 中执行它们:

                  • 编译:M-x 编译,然后输入你使用的命令
                  • 我的经验仅适用于 C++,但使用 g++,您可以按 C-x ` 跳转到编译器抱怨的行
                  • 运行 shell 命令:M-!,将输出转储到缓冲区中
                  • 交互式外壳:M-x 外壳
                • 或者,您可以像这样运行 emacs:

                  • emacs file.ext &
                  • 它会在后台打开 emacs,因此您仍然可以使用 shell(这最适用于 putty 和 X 转发,例如 Xming)

                【讨论】:

                  【解决方案16】:

                  当我在这里遇到这个问题时,我正试图解决同样的问题。我只是想补充一点,对我来说问题不是因为 emacs lisp 包的加载时间,而是主机没有完全解析的主机名这一事实

                  检查你的包加载时间做

                  M-x emacs-init-time
                  

                  对我来说是 0.3 秒,但加载时间却非常长。 正确更改我的主机名后,它解决了问题。

                  要配置完全解析的主机名,请编辑 /etc/hostname 和 /etc/hostsfile:

                  127.0.0.1       localhost localhost.localdomain
                  192.168.0.2   hostname hostname.domain
                  

                  【讨论】:

                    【解决方案17】:

                    我必须检查我的自定义,但是有一个名为 gnuserve 或 emacsclient 的包。它迁移了很多,所以你必须用谷歌搜索它。

                    它在后台运行一个 emacs 会话。任何进一步的 emacs 会话本质上只是该会话的新框架。一个优点是您以后的会话的启动时间很快。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-06-17
                      • 1970-01-01
                      • 2012-02-02
                      • 2011-08-06
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-01
                      相关资源
                      最近更新 更多