Если ваша программа работает правильно, но недостаточно быстро, и вы хотите заставить ее работать быстрее или эффективнее, первое, что следует сделать, это профилировать свой код, чтобы знать, где он тратит больше всего времени выполнения. Если вы обнаружите, что одна конкретная функция отвечает за значительную часть времени выполнения, вы можете начать искать способы оптимизации этой части.
Emacs имеет встроенную поддержку для этого. Чтобы начать профилирование, введите
M-x profiler-start. Вы можете выбрать периодический сбор использования ЦП (cpu), сбор при выделении памяти (memory) или оба. Затем запустите код, который вы хотите ускорить. После этого введите
M-x profiler-report, чтобы отобразить буфер с сводкой использования ЦП, собранного для каждого типа (cpu и memory), который вы выбрали для профилирования. Имена буферов отчетов включают время генерации отчетов, поэтому вы можете сгенерировать другой отчет позже, не стирая предыдущие результаты. Когда вы закончите профилирование, введите
M-x profiler-stop (профилирование имеет небольшие накладные расходы, поэтому мы не рекомендуем оставлять его активным, кроме случаев, когда вы действительно запускаете код, который хотите изучить).
Буфер отчета профилировщика показывает в каждой строке вызванную функцию, предшествованную абсолютным и процентным использованием ресурсов ЦП с момента начала профилирования. Если в данной строке слева от имени функции стоит символ ‘+’, вы можете развернуть эту строку, нажав 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).
Библиотека elp предлагает альтернативный подход, который полезен,
когда вы заранее знаете, какие функции Lisp вы хотите профилировать. Используя эту
библиотеку, вы начинаете с установки elp-function-list в
список символов функций — это функции, которые вы хотите профилировать. Затем введите
M-x elp-instrument-list RET nil RET, чтобы настроить профилирование этих функций. После выполнения кода, который вы хотите профилировать, вызовите
M-x elp-results, чтобы отобразить текущие результаты. Подробные инструкции см. в файле elp.el. Этот подход ограничен профилированием функций, написанных на Lisp; он не может профилировать примитивы Emacs.
Вы можете измерить время, необходимое для вычисления отдельных форм Emacs Lisp,
используя библиотеку benchmark. См. функцию
benchmark-call, а также макросы benchmark-run,
benchmark-run-compiled и benchmark-progn в
benchmark.el. Вы также можете использовать команду benchmark
для интерактивного измерения времени форм.
Чтобы профилировать Emacs на уровне его C-кода, вы можете скомпилировать его,
используя опцию --enable-profiling команды
configure. Когда Emacs завершает работу, он генерирует файл
gmon.out, который вы можете проанализировать с помощью утилиты
gprof. Эта функция в основном полезна для отладки Emacs. Она
фактически отключает команды M-x profiler-... на уровне Lisp,
описанные выше.