プログラムが正常に動作しているものの速度が十分ではなく、より高速に、あるいは効率的に動作させたい場合、まず最初に行うべきことは、コードをプロファイリングして、実行時間の大部分がどこに費やされているかを把握することです。もし、特定の関数が実行時間のかなりの割合を占めていることが分かったら、その部分を最適化する方法を探し始めることができます。
Emacsにはこれをサポートする機能が標準で備わっています。プロファイリングを開始するには、M-x profiler-start
と入力してください。CPU使用率を定期的にサンプリングする(cpu)、メモリが割り当てられた際にサンプリングする(memory)、またはその両方を行うかを選択できます。次に、高速化したいコードを実行してください。その後、M-x profiler-report
と入力すると、プロファイリング対象として選択した各タイプ(CPUおよびメモリ)でサンプリングされたCPU使用率のサマリーバッファが表示されます。レポートバッファの名前にはレポートが生成された時刻が含まれているため、以前の結果を消去することなく、後から別のレポートを生成できます。プロファイリングが完了したら、M-x profiler-stop
と入力してください(プロファイリングにはわずかなオーバーヘッドが伴うため、実際に調査したいコードを実行している時以外は、有効にしたままにしておくことは推奨しません)。
プロファイラレポートのバッファでは、各行に呼び出された関数が表示され、その前にはプロファイリング開始以降に消費されたCPUリソースの絶対量と割合が示されます。特定の行の関数名の左側に「+」記号がある場合は、RET と入力してその行を展開することで、上位関数から呼び出された関数を確認できます。プレフィックス引数(C-u RET)を使用すると、関数配下のコールツリー全体を表示できます。再度 RET を押すと、元の状態に戻ります。
j (profiler-report-find-entry) または mouse-2 を押すと、指定した位置にある関数の定義へジャンプします。d (profiler-report-describe-entry)
を押すと、関数のドキュメントを表示します。C-x C-w (profiler-report-write-profile) でプロファイルをファイルに保存し、M-x profiler-find-profile または M-x profiler-find-profile-other-window
で保存済みのプロファイルを読み込むことができます。= (profiler-report-compare-profile) で2つのプロファイルを比較できます。
elp ライブラリは代替的な手法を提供しており、プロファイリングしたい Lisp
関数があらかじめ分かっている場合に有用です。このライブラリを使用する場合、まず elp-function-list に関数シンボルのリスト(プロファイリングしたい関数)を設定します。次に
M-x elp-instrument-list RET nil RET
と入力して、それらの関数のプロファイリングを設定します。プロファイリングしたいコードを実行した後、M-x elp-results を呼び出して現在の結果を表示します。より詳細な手順については、ファイル
elp.el を参照してください。この手法は Lisp
で記述された関数のプロファイリングに限定されており、Emacs のプリミティブをプロファイリングすることはできません。
benchmark ライブラリを使用すると、個々の Emacs Lisp
フォームの評価にかかる時間を計測できます。benchmark.el にある関数 benchmark-call およびマクロ benchmark-run、benchmark-run-compiled、benchmark-progn を参照してください。また、benchmark コマンドを使用して、インタラクティブにフォームの計測を行うことも可能です。
EmacsをCコードレベルでプロファイリングするには、configureの--enable-profilingオプションを使用してビルドできます。Emacsが終了すると、gmon.outというファイルが生成され、これをgprofユーティリティで解析できます。この機能は主にEmacsのデバッグに有用です。なお、これにより前述のLispレベルのM-x profiler-…コマンドは動作しなくなります。