HN 日本語サマリー

← 一覧へ戻る
プログラミング

EmacsのConsultパッケージにおける非同期検索が遅く感じる理由と高速化の方法

Why Emacs Consult async searches feel slow and how to speed them up (jamescherti.com)

45 pointsby mpweiher19 コメント

要約

EmacsのConsultパッケージは、非同期検索機能を提供しますが、デフォルト設定では応答性が遅く感じられることがあります。この記事では、`consult-async-input-debounce`、`consult-async-input-throttle`、`consult-async-refresh-delay`といった設定変数を調整することで、検索のレイテンシを削減し、UIの更新頻度を上げる方法を解説しています。これらの設定は、CPU負荷やバッテリー消費とのトレードオフになるため、ユーザーの環境や好みに応じて最適化することが推奨されています。

全文翻訳

EmacsのConsultによる非同期検索が遅く感じる理由と高速化する方法? (consult-fd, consult-find, consult-grep, consult-ripgrep...)

consult Emacsパッケージは、consult-fd、consult-find、consult-grep、consult-git-grep、consult-ripgrepなどの非同期検索コマンドを提供します。これらのコマンドにおいて、Consultはミニバッファの入力が変更されるたびに必ずしも新しい検索を開始するわけではありません。その代わりに、設定可能なデバウンス(debounce)とスロットル(throttle)の遅延を使用して非同期プロセスの開始を制御し、別のリフレッシュ遅延(refresh delay)が非同期結果を完了UIにプッシュする頻度を制御します。

Consultを初めて試したとき、私は「Counselと比較して遅く感じる」と思いました(Emacsの設定であるshow-paren-delayについても同様の感覚がありました)。Counselでは、キーストロークごとに結果が即座に更新されましたが、Consultはリストを更新する前に、一瞬ためらうように見えました。

調べてみると、この動作は意図的なものであることがわかりました。現在のConsultのデフォルト設定は、意図的に保守的になっています。

アグレッシブな非同期検索

低レイテンシと速度を優先する場合、これらの変数をよりアグレッシブに設定できます。

(setq consult-async-input-debounce 0.05
      consult-async-input-throttle 0.1
      consult-async-refresh-delay 0.05)

これらの値は、Consultが別の非同期検索を開始するまでの待機時間を短縮し、完了UIがより頻繁にリフレッシュできるようになります。

これらの値は、基盤となる検索プログラムの実行速度を速くするものではありません。ripgrepのような外部ツールは、すでに高度に最適化されたマルチスレッドアルゴリズムを使用して、複数のCPUコアでファイルをスキャンしています。代わりに、これらの変数はEmacs自体のフィードバックループを高速化します。Consultが外部プロセスを起動するまでの待機期間を短縮し、Emacs UIが新しい非同期データをプルして画面をより高速に再描画するようにします。

変数: consult-async-input-debounce
(setq consult-async-input-debounce 0.05)

この設定は、最後のキーストロークから0.05秒後にConsultが非同期プロセスを起動するのを強制します。これは固定のポーリング間隔ではなくデバウンス遅延として機能するため、新しい入力があるたびにタイマーがリセットされます。検索は、完全な静止期間が経過した後にのみ実行されます。

これにより、入力する中間文字ごとにEmacsが無駄なバックグラウンドタスクを起動するのを防ぎ、CPUオーバーヘッドを最小限に抑え、UIの応答性を維持します。

変数: consult-async-input-throttle
(setq consult-async-input-throttle 0.1)

consult-async-input-throttle変数は、Consultが非同期プロセスを開始できる頻度に対する厳格なレート制限として機能します。この値を使用すると、入力速度に関係なく、新しいプロセスは0.1秒ごとに最大1回開始されます。

この2つの概念の違いを分解すると、以下のようになります。

  • デバウンスはアイドルタイマーです。入力が停止するのを待ちます。キーを押し続けると、タイマーはリセットされ続け、検索は入力が停止するまで実行されません。
  • スロットルは厳格な速度制限です。最大実行レートを強制します。単語間にわずかな間隔を空けてデバウンスタイマーを常にトリガーできる場合でも、スロットルによりシステムが許可されたレートを超えることがないことが保証されます。
変数: consult-async-refresh-delay
(setq consult-async-refresh-delay 0.05)

consult-async-refresh-delay変数は、Consultが非同期コマンドからの結果を完了UIにどのくらいの頻度で更新するかを制御します。この値により、Consultは新しい結果の更新が必要な場合に、0.05秒という短い間隔でリフレッシュします。表示する新しいものがなくても、Emacsが継続的に再描画されるわけではありません。

低いリフレッシュ遅延は検索結果をより速く表示できるようにしますが、再表示自体にはコストがかかります。Emacsの再表示は十分にコストがかかるため、非常に頻繁な更新はCPUとガベージコレクションのアクティビティを増加させる可能性があります。

値の選択

非同期検索を可能な限り応答性の高いものにしたい場合、これらの値は低い入力レイテンシとリソース使用量の間の良いバランスを提供します。Consultはミニバッファの変更に迅速に応答し、最小限の遅延で完了UIを更新します。

これらの設定は、電源に接続された高速なコンピューターに適しています。ラップトップでは、アグレッシブなプロセス作成と継続的なUI更新により、CPUがアクティブになり、保守的なデフォルト設定よりもバッテリーが早く消耗します。低速なコンピューターや非常に大きなプロジェクトを検索する場合、デフォルト値は入力がまだ変更されている間に不要な検索を回避することで、より良いバランスを提供する可能性があります。

最適な値は、タイピング速度、プロジェクトサイズ、検索ツールのパフォーマンス、電力制約、およびEmacsでの非同期結果の処理と再表示のコストに依存します。したがって、遅延を下げることは、より頻繁な非同期作業と引き換えに、入力レイテンシを減らすという明示的なトレードオフとして見るのが最善です。