0Pricing
R Academy · Урок

Бенчмаркинг с помощью microbenchmark

Статистически сравнивайте несколько реализаций с помощью microbenchmark()

«Бенчмаркинг с помощью microbenchmark» — бесплатный урок R Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Зачем нужен microbenchmark?

Функция system.time() измеряет время с точностью до миллисекунд и ненадёжна для быстрых операций. Пакет microbenchmark выполняет выражения сотни раз, учитывает прогрев и сообщает статистику с точностью до наносекунд — поэтому он подходит для сравнения похожих реализаций.

Основы использования microbenchmark

Передайте именованные выражения в microbenchmark(). Имя каждого аргумента станет меткой в выводе. Аргумент times задаёт, сколько раз вычисляется каждое выражение.

# library(microbenchmark)
# x <- 1:10000
#
# microbenchmark(
#   loop = {
#     s <- 0
#     for (v in x) s <- s + v
#   },
#   vectorized = sum(x),
#   times = 200L
# )

Выбор аргумента times

Большее число повторений даёт более стабильные оценки, но увеличивает время выполнения. Общие рекомендации:

  • Быстрые выражения (микросекунды): times = 1000L или больше
  • Умеренно быстрые (миллисекунды): times = 100L
  • Медленные (секунды): times = 10L или меньше

По умолчанию используется times = 100L — это хорошая отправная точка.

# library(microbenchmark)
# microbenchmark(
#   fast_op = sqrt(2),
#   times = 10000L   # many reps for a nanosecond-scale operation
# )
# microbenchmark(
#   slow_op = sort(rnorm(1e6)),
#   times = 10L      # fewer reps for second-scale operation
# )

Задание аргумента unit

Используйте аргумент unit, чтобы отображать результаты в удобном масштабе:

  • 'ns' — наносекунды (для очень быстрых операций)
  • 'us' — микросекунды
  • 'ms' — миллисекунды
  • 's' — секунды
  • 'relative' — отношение ко времени самого быстрого выражения
# library(microbenchmark)
# x <- runif(1000)
#
# microbenchmark(
#   sapply_sqrt = sapply(x, sqrt),
#   vectorized  = sqrt(x),
#   times = 500L,
#   unit = 'us'   # display in microseconds
# )

Интерпретация сводного вывода

microbenchmark выводит сводную таблицу со следующими столбцами:

  • min — самый быстрый отдельный запуск
  • lq / mean / median / uq — нижний квартиль, среднее, медиана, верхний квартиль
  • max — самый медленный отдельный запуск
  • neval — число вычислений

Используйте median как основной показатель для сравнения: он устойчив к случайным паузам сборщика мусора, которые завышают max и mean.

# Example summary output (unit: microseconds):
#
#         expr    min     lq   mean  median    uq    max neval
#         loop 1203.1 1245.3 1301.7  1262.4 1310.1 2100.8   100
#   vectorized    2.1    2.3    2.9     2.4    2.6   18.3   100
#
# => vectorized is ~525x faster at median
cat('Always compare medians, not means, for microbenchmark results
')

summary() для объекта microbenchmark

Вызов summary(mb) для сохранённого результата microbenchmark возвращает таблицу данных, которую можно программно анализировать. В вызове сводки также можно изменить unit.

# library(microbenchmark)
# x <- rnorm(5000)
# mb <- microbenchmark(
#   vapply_abs  = vapply(x, abs, numeric(1)),
#   base_abs    = abs(x),
#   times = 200L
# )
# s <- summary(mb, unit = 'ms')
# print(s[, c('expr', 'min', 'median', 'max')])

autoplot() для визуального сравнения

autoplot(mb) использует ggplot2, чтобы построить скрипичный или коробчатый график распределений времени выполнения для разных выражений. Так легко увидеть не только различия медиан, но и разброс, а также перекрытие результатов альтернативных вариантов.

# library(microbenchmark)
# library(ggplot2)
#
# x <- 1:50000
# mb <- microbenchmark(
#   loop   = { s <- 0; for (v in x) s <- s + v },
#   vapply = vapply(x, identity, numeric(1)),
#   vec    = sum(x),
#   times  = 100L
# )
# autoplot(mb)  # opens ggplot2 violin chart

Сравнение цикла, vapply и sapply

Классический пример для сравнения: поэлементное применение функции с помощью цикла for, sapply() или vapply(). vapply() быстрее sapply(), потому что заранее выделяет память под вектор результата. Оба варианта медленнее полностью векторизованного кода.

# library(microbenchmark)
# x <- runif(5000, 1, 100)
#
# mb <- microbenchmark(
#   for_loop = {
#     r <- numeric(length(x))
#     for (i in seq_along(x)) r[i] <- log(x[i])
#   },
#   sapply_log  = sapply(x, log),
#   vapply_log  = vapply(x, log, numeric(1)),
#   vec_log     = log(x),
#   times = 200L, unit = 'us'
# )
# print(mb)

Сначала проверьте корректность

Перед измерением производительности убедитесь, что все выражения возвращают одинаковые результаты. Быстрая, но некорректная реализация бесполезна. Для сравнения результатов используйте identical() или all.equal().

# x <- runif(1000)
# r1 <- sapply(x, sqrt)
# r2 <- sqrt(x)
# r3 <- vapply(x, sqrt, numeric(1))
#
# stopifnot(isTRUE(all.equal(r1, r2)))
# stopifnot(isTRUE(all.equal(r1, r3)))
# cat('All three produce identical results -- safe to benchmark
')
cat('Always verify correctness before comparing speed
')

Измерение с аргументом setup

Используйте аргумент setup, чтобы выполнить код один раз перед измеряемыми выражениями. Это позволяет не включать время создания данных в измерение, если создание данных не является предметом сравнения.

# library(microbenchmark)
#
# microbenchmark(
#   sort_base  = sort(x),
#   sort_order = x[order(x)],
#   setup = { x <- rnorm(10000) },
#   times = 100L
# )
# Each iteration refreshes x via setup, then times sort_base and sort_order

Представление результатов измерений в анализе

При публикации результатов измерений всегда указывайте:

  • версию R и платформу
  • версии пакетов
  • использованное значение times
  • размер набора данных, на котором проводилось измерение

Время выполнения нельзя напрямую переносить с одной машины на другую — при сравнении реализаций сообщайте относительные соотношения, а не абсолютные значения.

cat('R version    :', R.version$version.string, '
')
cat('Platform     :', R.version$platform, '
')
cat('Logical cores:', parallel::detectCores(), '
')

Быстрая проверка: показатель microbenchmark

Какая сводная статистика из вывода microbenchmark наиболее надёжна при сравнении двух реализаций?

Повторение: microbenchmark

microbenchmark — стандартный инструмент для строгого измерения производительности небольших фрагментов кода в R:

  • Передавайте именованные выражения и задавайте times, чтобы управлять числом повторений
  • Используйте unit = 'us' или 'ms' для удобного чтения результатов
  • Сравнивайте медианы — они устойчивы к выбросам, вызванным сборкой мусора
  • Используйте autoplot() для визуализации распределений времени выполнения
  • Перед измерением проверяйте корректность с помощью all.equal()

Часто задаваемые вопросы

Урок «Бенчмаркинг с помощью microbenchmark» бесплатный?

Да — полный текст урока «Бенчмаркинг с помощью microbenchmark» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Бенчмаркинг с помощью microbenchmark»?

Статистически сравнивайте несколько реализаций с помощью microbenchmark() Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Бенчмаркинг с помощью microbenchmark»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. system.time() и proc.time()
  2. Профилирование кода с помощью Rprof и profvis
  3. Векторизация для ускорения
  4. Бенчмаркинг с помощью microbenchmark
← Назад к R Academy