起動時間を短縮するにはどうすればよいですか?


41

起動時間を短縮するためにできる基本的なことは何ですか?

その点で、特に注意すべき点はありますか?

注:起動時間は、Emacsをあまり頻繁に起動せず(セッションごとに1回)、実行中のインスタンスでファイル開くことで軽減できます。この質問は、セッションの開始時、またはEmacsの起動が必要な他の時のために、起動時間を最小限にすることに関するものです。


Stack Overflowで回答された同じ質問もご覧ください。質問と回答のスコアは50を超えており、30の「お気に入り」のブックマークがあります。ここでの良い答えは、Stack Overflowで利用できるものを超えるはずです。


1
これに関するデータが欲しいのですが、ほとんどのユーザーには、起動時間の大部分を占める1つまたは2つのパッケージがあると思います。私の場合、それは実権を握っていました。helmを使用する場合、実際に初期化を延期することはできないので、すぐに使用できる状態にしておく必要があります。ツタに切り替えたところ、開始時間が約12秒から1秒未満に短縮されました。サーバー/クライアントのセットアップの使用を停止しました。(ちなみに、私は起動時間を短縮するように切り替えませんでした。それはちょうどいい副次的な利点でした。)
オマー

回答:


43

削減に関する私のポイントは次のとおりですemacs-init-time。これはデーモンやサーバーの使用などをカバーしていません。もちろん、emacsを閉じることはめったにありません。

しないでください:

  • パッケージに適切な自動ロードCookieがない場合は、initにパッケージを必要としないでください。入力コマンドで自動ロードを設定してください。したがって、初めてパッケージを使用するときにfoobar呼び出しが行われfoobar-modefoobar事前に自動ロードされていない場合は、次のようなものが必要になります。

    (autoload 'foobar-mode "foobar")
    

    これによりfoobar-modefoobarパッケージがまだロードされていない場合でも呼び出すことができます。この方法foobarは、実際に呼び出すまでロードされませんfoobar-mode

  • package-refresh-contents起動時にパッケージをインストールする必要がない場合は実行しないでください。不足しているパッケージを自動インストールするように設定している場合は、コマンドライン引数を設定して、自動インストールをいつ実行するかを指定することを検討してください。

  • 上記のように、ネットワークに関連することは何もしないでください。
  • desktop本当に必要な場合以外は、initをロードしないでください。

行う

  • use-packageパッケージの管理などに使用してください。これにより、必要なもの、後で読み込むもの、自動で読み込むものを簡単に指定でき、パッケージごとにinitのプロファイルを簡単に作成できます。

  • テーマのロードと有効化の違いを知ってください。つまり、必要な数だけ読み込むことができますが、複数有効にしないでください。理想的には、1つのテーマのみをロードして有効にします。load-themeテーマの有効化を防ぐためにオプションの引数が必要です。起動時に遅くて見苦しい複数のテーマを誤って有効にするのは簡単です。

  • チートを行います:多くの場合、initでロードする大規模なグローバルモード(アンドゥツリー、オートコンプリート、idoモードなど)があります。エントリ関数にautoloadsが設定されていることを確認し、initでアイドルタイマーを起動してパッケージをロードします。私はこれを行いますがundo-tree-modeido実際にはそれらを使用する必要があり、すでにロードされているため、他のユーザーは遅延に気付きません。

    更新:use-packageが少し変更されました。タイマー機能の使用を開始する前に公式のreadmeを読んでください。

    たとえば、ロードを少し遅らせたい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)
    
  • 初期化のプロファイルを作成してください。本当のスローダウンがどこにあるかを見るのはいつも驚くことです。profile-dotemacs.elは、初期化を6秒から1秒未満に短縮するために使用してきた素晴らしいツールです。

適切に構成されたuse-packageinitは非常に高速です。initをバイトコンパイルせず、use-package95個のパッケージの構成に使用し、1秒未満で起動します。


7
「initのプロファイルを作成してください。本当のスローダウンがどこにあるかを見るのはいつも驚くことです。」ネタバレ注意、それはその(require 'org)行です。:-)
マラバルバ

@Jordan、エントリ関数が自動ロード設定を持っていることを確認してから、特にundo-tree-modeの場合、initでアイドルタイマーを起動してパッケージをロードする方法について少し拡張していただけますか?ありがとう。
フランシスコディバー14年

@FranciscoDibar投稿を例で更新しました。
ジョーダンビオンド14年

2
私はすぐにido-modeを使用します。smexのCx CfまたはMxは、emacsを開いたときにほとんど常に最初のものであり、問​​題に気付いたことはありません。また、emacsを開いてから1秒以内に何かを元に戻したい場合は...それについては何も言えません。本当に心配な場合は、自分で試してみるか、非アイドルタイマーを使用するか、初期化フックを使用してください。
ジョーダンビオンド14年

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 # '`コマンドです。
アンドリュースワン

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は(デフォルトの〜800kbの代わりに)〜50MBごとに呼び出されます。これは、十分なRAMを備えた最新のシステムでは適切と思われます。


1
その値が(a)おそらくあなたが必要とするよりもはるかに高いことを除いて(その10分の1と違いは見られません)。(b)GCのしきい値が大きいと、GCが発生するたびに遅延が長くなるため、明らかに、起動後も保持したい値ではありません。initに対して高く設定した場合は、initの後に再び低く設定し直してください。それemacs-startup-hookはそうするのに良い場所だと思います。
phils

1
@philsありがとう!(a)私のセットアップでは、50Mbは最小数のGC(および最小の起動時間)を提供します。10Mb程度に低くすると、その差は顕著/測定可能です(実際にはあまり変化しませんが...)(b)いいですね、ありがとう。コメントを反映するように投稿を編集しました。
ffevotte

6

起動時間の最適化に費やす時間は、Emacsの起動を待たなければならなかった余分な時間よりも長くなる可能性があります。

現時点ではrequire、Flycheckがコード内のスペルエラーを検出できるように、initファイルで25回の呼び出しを行います。起動時間は...

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

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

また、私のシステムにtime emacs -Q --eval '(save-buffers-kill-terminal)'はがrealあり0m0.404sます。私が節約できる理論上の最大時間は2.3秒です。

初期化ファイルの最適化をすべて行うのに1時間を費やしたとします。(バイトコンパイルされたinitファイルが原因で変更が有効にならない理由を解明するために、後日15〜30分を費やした時間はカウントしません。)(また、requireコールを削除しなかった場合、Flycheckを使用するとデバッガで節約できました。)1時間に3600秒あります。したがって、2.3秒全体を節約できた場合、時間の投資は1565の起動後にのみ報われます。

毎日3回Emacsを再起動したと仮定すると、その投資が完済するのに1年半かかります。同じEmacsインスタンスを一度に何日も実行したままにしておくと(私が頻繁に行うように)、週に2〜5回しか再起動しません。その場合、その投資が完済するのに6〜15年かかります。

私は寛大です、なぜならあなたはあなたのスタートアップを最適化するのに1時間以上費やす可能性が高く、おそらくあなたはおそらく理論上の最大秒数を節約しないでしょうから。


12
しかし、あなたは潜在的に幸せになるでしょう。
phils

2
それは一人にとっては真実かもしれませんが、StackExchangeの重要なポイントは共有です。1人の人が見つけるのに30分かかるが、何十人もの人の起動時間を1秒短縮するトリックについてはどうでしょうか。あなたはまだそれを悪い投資と考えますか?
ffevotte

@phils皮肉なことに、私は同じことを言うことを考えましたが、私自身の視点を支持しています!「起動時間についてうめく前に、「これを最適化するのに時間を浪費しなかったことを嬉しく思います!」と考えてください。」
ジャクソン

@Francescoそして、この投稿は何十人もの時間を節約する私のトリックです。
ジャクソン

@Jacksonこの特定の問題についてはまだ同意していませんが、少なくとも今はあなたの意見がわかります。ありがとう:)
ffevotte
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.