移転しました。

約3秒後に自動的にリダイレクトします。

巨大なプロジェクト以下でEmacsのファイルオープンが遅いので調査する

最近非常にコードベースの大きいプロジェクトを扱うことがあって、emacsでファイル遷移をすると異様に読み込みに時間がかかっていました。 init.elを見る限り、hookしている処理に重そうなものはなさそうですが、はて、何に時間が食われているのだろう?

ファイルを開くときの処理をdumpして、何に処理時間がかかっているのかをつきとめたい。 そこで、emacsのプロファイラを利用してどの関数が時間を食っているのか探ってみました。

qiita.com

こちらの記事にEmacsのプロファイリング機能が日本語でまとまっていて、参考になります。 今回は素直に profiler-start を使ってcpu dumpをしてみます。

手順としては、

  1. まず profiler-start をしておく。cpuを選択
  2. ファイル遷移を実施
  3. profiler-report を実行する
  4. 解析が終わったら profiler-end でプロファイラを止める

cpu利用時間で計測結果を出すとこんな感じになります。 どこの処理に時間がかかっているのか、パーセンテージで表示されるのでボトルネックを探しやすいです。

emacs profiler cpu report

これを見ると、 projectile-update-mode-line が時間を食っていそうです。

自分のモードラインでは projectile の情報を表示に利用していないので、これはOFFにしてしまってもよさそうです。

    (setq projectile-dynamic-mode-line nil)

こんな感じで、十分早くなるまで解析と、改善施策を入れていきます。いわゆる普通のパフォーマンスチューニングです。

最終的に私のボトルネックprojectile-project-root に帰結しました。

many projectile-project-root

このように、 projectile-project-root が沢山呼ばれていることがわかります。ここではプロジェクトのルートディレクトリの探索をしているはず。 探索のための関数はinit.elから設定できますが、これまで特に困ってなかったので、私はデフォルトのままになっています。

docs.projectile.mx 公式ガイドによると、 projectile-root-top-down は3番目なので、その前の関数では見つかっていないようです。

(defcustom projectile-project-root-functions
  '(projectile-root-local
    projectile-root-bottom-up
    projectile-root-top-down
    projectile-root-top-down-recurring)
  "A list of functions for finding project roots."
  :group 'projectile
  :type '(repeat function))

1番目の projectile-root-local については、以下のように説明されています。

  • projectile-root-local: looks for project path set via the buffer-local variable projectile-project-root. Typically you’d set this variable via .dir-locals.el and it will take precedence over everything else.

つまり、 .dir-locals.dl にプロジェクトルートを示しておけば、探索自体しなくてよさそうな気がします。

    ((nil . ((projectile-project-root . "/mnt/c/path/to/project/root")))
     (c++-mode . ((indent-tabs-mode . t))))

びっくりするくらい早くなりました! あとは .dir-locals.elVCSで管理するなり、ignoreするなりしておけば万事解決です。

まとめ

今回はEmacsに付属しているプロファイラを利用して、普段使いで気になった重い動作を調査して、チューニングしてみました。 ちょっと気になる動作があるときに、簡単に実施できて便利だと思いました。他にもトレーサーなどもあるので、場合によって色々試せそうです。

それではよいEmacsライフを!