我怎样做才能加快启动速度?


41

我可以做些基本的事情来减少启动时间?

就此而言,我是否需要特别注意什么?

注意:可以通过减少启动Emacs的频率(每次会话一次)并在正在运行的实例中打开文件来减少启动时间。这个问题是关于最小化启动时间,会话启动或需要启动Emacs的任何其他时间。


另请参见在Stack Overflow上回答的同一问题,问答得分超过50和30多个“收藏夹”书签。好的答案应该超出Stack Overflow的可用范围。


1
我很想获得有关此方面的数据,但我的猜测是,对于大多数用户而言,一两个软件包占用了大量启动时间。就我而言,这是掌舵人。请注意,如果您使用头盔,则无法真正推迟其初始化,而是希望它可以立即使用。我改用常春藤,这使我的开始时间从大约12秒减少到不到一秒钟。我什至停止使用服务器/客户端设置。(顺便说一句,我没有选择减少启动时间,这只是一个不错的附带好处。)
Omar

Answers:


43

这是我关于reduce的观点emacs-init-time,它不涉及使用守护程序或服务器之类的事情,不用说,您永远都不应关闭emacs。

别:

  • 不需要init中的软件包,如果软件包没有正确的自动加载cookie,请确保在入口命令上设置了自动加载。因此,如果您第一次使用包foobar是通过调用foobar-modefoobar不是预先自动加载的,则将需要以下内容:

    (autoload 'foobar-mode "foobar")
    

    这样foobar-mode即使在foobar尚未加载软件包的情况下,您也可以拨打电话。foobar在您实际致电之前,不会加载这种方式foobar-mode

  • package-refresh-contents如果您不需要在启动时安装软件包,请不要运行。如果您将init设置为自动安装丢失的软件包,请考虑设置命令行arg,以指定何时进行自动安装。

  • 像上面一样,不要做任何与网络相关的事情。
  • desktop除非您确实想要,否则不要在init上加载您的内容。

  • 请使用类似的方法use-package来管理您的包裹。这样可以很容易地指定需要什么,以后要装载什么,自动装载什么,并使按包装对初始配置进行概要分析变得容易。

  • 是否知道加载主题和启用主题之间的区别。简而言之,您可以加载任意数量的文件,但请确保不要启用多个文件。理想情况下,仅加载并启用一个主题。load-theme需要一个可选的arg来防止启用主题。意外地启用多个主题很容易,这在启动时很慢而且很丑陋。

  • 做作弊:您通常需要在初始化时加载大型全局模式,例如undo-tree,autocomplete,ido-mode等。确保进入功能具有自动加载设置,然后在初始化中启动空闲计时器以加载程序包。我会这样做undo-tree-modeido而其他人则永远不会注意到延迟,因为在我实际需要使用它们时,它们已经加载了。

    更新:use-package有所更改,请在开始使用计时器功能之前阅读官方自述文件。

    例如:如果您想稍微延迟加载时间,global-undo-tree-mode可以将其放在您的init中:

    (run-with-idle-timer 1 nil (lambda () (global-undo-tree-mode t)))
    

    现在,您的初始化可以继续愉快地进行,global-undo-tree-mode直到其他所有内容准备就绪并且您处于方向盘之后,才会真正被激活。

    use-package支持使用:idle关键字内置的这种行为。这是undo-tree我的.init.el 的配置:

    (use-package undo-tree
      :idle (global-undo-tree-mode 1)
      :bind (("C-c j" . undo-tree-undo)
             ("C-c k" . undo-tree-redo)
             ("C-c l" . undo-tree-switch-branch)
             ("C-c ;" . undo-tree-visualize))
      :ensure t)
    
  • 剖析您的init,看到真正的减速在哪里总是令人惊讶的。profile-dotemacs.el是一个了不起的工具,我曾用它来帮助我将初始化过程从〜6秒降低到<1秒。

配置良好的use-package初始化可能会非常快。我不对自己的init进行字节编译,它用于use-package配置95个程序包,并在<1秒内启动。


7
“分析您的init,看到真正的速度下降总是令人惊讶的。” 剧透警报,就是那条(require 'org)线。:-)
马拉巴巴2014年

@Jordan,能否请您扩展一下如何确保入口函数具有自动加载程序设置,然后在init中启动空闲计时器以加载程序包,尤其是对于undo-tree-mode?谢谢。
Francisco Dibar 2014年

@FranciscoDibar我用示例更新了我的帖子。
Jordon Biondo

2
我立即使用ido-mode,当我打开emacs时,我几乎总是第一时间使用smx的Cx Cf或Mx,而且我从来没有注意到任何问题。另外,如果您想在打开emacs的一秒钟之内撤消某些操作,那么我对此无话可说。如果您真的很担心,请自己尝试一下,或者只使用一个非空闲计时器或在执行初始化钩子之后。
Jordon Biondo

1
空闲计时器建议很有用。稍短的加载语法是(run-with-idle-timer 1 nil #'global-undo-tree-mode)'. If the function you are loading takes parameters you can just provide them after the #'`命令。
Andrew Swann

8

最近在emacs reddit上弹出的内容:将其放在init文件的开头附近,以减少垃圾回收调用的次数:

(setq gc-cons-threshold 50000000)

(add-hook 'emacs-startup-hook 'my/set-gc-threshold)
(defun my/set-gc-threshold ()
  "Reset `gc-cons-threshold' to its default value."
  (setq gc-cons-threshold 800000))

在上面的示例中,GC每〜50MB(而不是默认值〜800kb)被调用一次,这在具有大量RAM的现代系统上似乎是明智的。


1
除了这个值(a)可能比您需要的高得多(我认为其中的十分之一没有区别);(b)显然不是您想要在启动后继续保持的值,因为GC阈值较高意味着每次发生GC时都会有较长的延迟。如果将它设置为较高的init,请在初始化后再将其设置回较低。我认为那emacs-startup-hook是个好地方。
phils 2015年

1
@phils谢谢!(a)在我的设置中,50Mb可以提供最少数量的GC(以及最少的启动时间)。如果我低至10Mb,则差异是明显的/可测量的(尽管在实践中并没有太大变化...)(b)好的主意,谢谢。我修改了帖子以反映您的评论。
ffevotte 2015年

6

您花费在优化启动时间上的时间可能要比等待Emacs启动所需的所有额外时间都要长。

目前,我require在初始化文件中进行了25次调用,以便Flycheck可以在我的代码中发现拼写错误。我的启动时间是...

$ time emacs --eval '(save-buffers-kill-terminal)'

real    0m2.776s
user    0m2.305s
sys     0m0.148s

另外,我的系统上,time emacs -Q --eval '(save-buffers-kill-terminal)'有一个real0m0.404s。我可以节省的理论上最大时间为2.3秒。

假设我花了一个小时对初始化文件进行所有优化。(我不会计算稍后花费的额外15-30分钟时间,以弄清为什么由于我的init文件被字节编译而导致我的更改未生效。)(我也不会计算该时间如果我没有删除require呼叫,Flycheck会把我保存在调试器中。)一个小时中有3600秒,因此,如果我节省了整整2.3秒,那么我的时间投入只有在1565个创业公司之后才能得到回报。

假设我每天重新启动Emacs 3次,那么每天需要花费一年半的时间才能收回投资。如果我一次使同一个Emacs实例一次运行几天(就像我经常做的那样),那么我大概每周只能重启2-5次,在这种情况下,这笔投资需要6到15年的时间才能收回。

我很慷慨,因为您可能要花一个多小时来优化启动,而且您可能不会节省理论上的最大秒数。


12
但是您可能会更快乐。
菲尔斯2015年

2
对于一个人来说可能是正确的,但是StackExchange的重点是共享。一个花30分钟才能找到一个人,却将数十人的启动时间缩短了1秒的花样呢?您是否仍然认为这是一项不良投资?
ffevotte 2015年

@phils具有讽刺意味的是,我考虑过要说同样的话,但是要支持我自己的观点!“在抱怨自己的启动时间之前,请想一想,'我很高兴我没有浪费时间优化它!'”
杰克逊

@Francesco这是我的技巧,可以节省数十个人的时间。
杰克逊

@Jackson在这个特定问题上,我仍然不同意您的看法,但至少现在我明白您的意思了。谢谢:)
ffevotte
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.