Какие средства использовать для анализа производительности?

Для анализа производительности в Elixir существует ряд встроенных и внешних инструментов. Они позволяют измерять время выполнения кода, профилировать нагрузку, отслеживать потребление памяти, наблюдать за процессами и оценивать поведение системы в реальном времени.

1. :timer.tc/1, :timer.tc/2, :timer.tc/3

Эти функции из Erlang возвращают время в микросекундах, потраченное на выполнение функции.

{time_microsec, result} = :timer.tc(fn -> heavy_function() end)
IO.puts("Execution time: #{time_microsec / 1_000} ms")

Полезно для грубой оценки времени выполнения отдельных вызовов.

2. Benchee

Это полноценная библиотека для микробенчмаркинга.

Установка:

Добавь в mix.exs:

def deps do
\[
{:benchee, "~> 1.0", only: :dev}
\]
end

Использование:

Benchee.run(%{
"Enum.map" => fn -> Enum.map(1..1000, & &1 \* 2) end,
"List comprehension" => fn -> for x <- 1..1000, do: x \* 2 end
})

Покажет среднее, минимальное, максимальное время выполнения, стандартное отклонение, сравнение разных реализаций.

3. :fprof

Инструмент для глубокой трассировки и анализа, встроенный в Erlang. Он профилирует вызовы функций и строит отчёты по времени исполнения и количеству вызовов.

Пример:

:fprof.trace(start: self())
:ok = :fprof.apply(&your_function/0, \[\])
:fprof.trace(:stop)
:fprof.profile()
:fprof.analyse(dest: 'fprof.analysis')

Отчёт можно просмотреть в консоли или экспортировать в файл.

4. :eprof

Менее подробный, но более быстрый профилировщик. Даёт сводку по времени, потраченному каждой функцией.

:eprof.start_profiling(\[self()\])
your_function()
:eprof.stop_profiling()
:eprof.analyze()

5. :observer

Графический инструмент из OTP.

Запуск:

:observer.start()

(На macOS или Linux может потребоваться установка GUI зависимостей)

Функциональность:

  • наблюдение за процессами (PID, сообщения, память);

  • использование CPU и памяти;

  • дерево процессов;

  • ETS, Mnesia, таблицы;

  • графики и диаграммы.

Очень полезен для отладки и мониторинга системы в реальном времени.

6. Telemetry

Библиотека для сбора метрик и логирования производительности в продакшене и тестах.

Подключение:

{:telemetry, "~> 1.0"}

Генерация событий:

:telemetry.execute(\[:my_app, :process\], %{duration: 120}, %{id: 1})

Подписка:

:telemetry.attach("log-duration", \[:my_app, :process\], fn event, measure, meta, \_config ->
IO.inspect({event, measure, meta})
end, nil)

Можно подключить к сбору системных метрик, обработки запросов, сообщений и др.

7. Telemetry + Prometheus + Grafana

В боевых условиях Telemetry комбинируется с:

  • Telemetry.Metrics — для определения метрик;

  • TelemetryMetricsPrometheus — экспорт метрик в формате Prometheus;

  • Grafana — визуализация производительности на дашбордах.

8. :erts_debug.size/1, :erlang.memory/0

Для измерения потребления памяти:

:erts_debug.size(my_large_struct)
:erlang.memory()

memory() возвращает структуру: :total, :processes, :atom, :binary, :code, :ets.

9. :erlang.statistics/1

Позволяет измерить:

  • :wall_clock — общее прошедшее время;

  • :runtime — CPU-время;

  • :reductions — количество редукций (единиц вычислений).

Пример:

:erlang.statistics(:reductions)

10. :dbg — отладка и трассировка

Инструмент трассировки вызовов, аналог strace.

:dbg.tracer()
:dbg.p(:all, :c)
:dbg.tpl(MyModule, :\_, :x)

После запуска каждая вызванная функция будет логироваться. Позволяет отслеживать задержки и сложные зависимости.

11. Recon, ExProf, Exometer

Дополнительные сторонние инструменты:

  • Recon — продвинутый инструмент наблюдения за работающей системой. Позволяет смотреть память, процессы, нагрузки, сокеты.

  • ExProf — удобная обёртка над :fprof.

  • Exometer — система сбора метрик с гибкой конфигурацией.

12. Инструменты встроенные в BEAM

  • Планировщик (scheduler) управляет распределением процессов;

  • Garbage Collector (GC) — виден через :observer и :erlang.process_info/2;

  • ETS и процессы используют раздельную память.

Использование лёгких процессов вместо потоков даёт огромные преимущества в масштабируемости, но требует чёткого мониторинга нагрузки, так как ошибки одного процесса не должны влиять на другие.

Эти инструменты дают полный контроль над измерением и анализом производительности в Elixir-приложениях — от простой замерки времени до построения распределённого мониторинга с визуализацией.