0Pricing
Ruby Academy · Урок

Измерение производительности

Модуль Benchmark

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

Зачем измерять?

Оптимизация без измерений — это гадание. Модуль Benchmark из стандартной библиотеки Ruby точно измеряет время выполнения кода.

  • Находите медленные участки до их изменения
  • Объективно сравнивайте реализации
  • Избегайте преждевременной оптимизации
require 'benchmark'

time = Benchmark.realtime do
  1_000_000.times { |i| i * 2 }
end
puts "Took #{time.round(4)}s"

Benchmark.measure

Benchmark.measure возвращает отчёт о пользовательском, системном и реальном времени.

  • Пользовательское время — это время CPU, затраченное вашим кодом
  • Реальное время — это прошедшее время по часам
require 'benchmark'

result = Benchmark.measure do
  500_000.times { |i| i.to_s }
end
puts result

Benchmark.bm

Benchmark.bm запускает несколько блоков и помечает их в таблице.

  • Передайте ширину метки для выравнивания
  • Каждый вызов x.report занимает одну строку
require 'benchmark'

Benchmark.bm(10) do |x|
  x.report('to_s:') { 100_000.times { |i| i.to_s } }
  x.report('inspect:') { 100_000.times { |i| i.inspect } }
end

Benchmark.bmbm

Benchmark.bmbm сначала выполняет пробный прогон, чтобы прогреть кэши и сборщик мусора и получить более достоверные результаты.

  • Первый проход отбрасывается
  • Второй проход является настоящим измерением
require 'benchmark'

Benchmark.bmbm do |x|
  x.report('sum:') { (1..100_000).sum }
  x.report('reduce:') { (1..100_000).reduce(:+) }
end

Быстрое измерение времени с realtime

Benchmark.realtime возвращает только секунды, прошедшие по часам, в виде числа с плавающей точкой.

  • Это самый простой способ измерить время одного блока
  • Подходит для разовых проверок
require 'benchmark'

elapsed = Benchmark.realtime do
  arr = Array.new(100_000) { rand }
  arr.sort
end
puts "Sorted in #{elapsed.round(4)}s"

Монотонные часы

Для точного измерения времени, не зависящего от изменений системных часов, используйте Process.clock_gettime с монотонными часами.

  • Не зависит от корректировок NTP
  • Самый точный встроенный вариант
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
200_000.times { |i| i * i }
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
puts "Elapsed: #{(finish - start).round(4)}s"

Сравнение двух подходов

Тесты производительности особенно полезны при сравнении вариантов. Запускайте оба варианта при одинаковой нагрузке.

  • Размер входных данных должен быть достаточно большим для измерения
  • Повторяйте измерения, чтобы уменьшить шум
require 'benchmark'

arr = (1..100_000).to_a
Benchmark.bm(8) do |x|
  x.report('map:') { arr.map { |n| n * 2 } }
  x.report('each:') { r = []; arr.each { |n| r << n * 2 } }
end

Остерегайтесь микроизмерений

Крошечные тесты производительности могут вводить в заблуждение.

  • JIT и кэши могут не отражать реальные рабочие нагрузки
  • Сборщик мусора может сработать во время измерения
  • Измеряйте реалистичные объёмы данных
require 'benchmark'

# Too small to be meaningful
t = Benchmark.realtime { 10.times { |i| i + 1 } }
puts "Misleadingly tiny: #{t}s"

Итераций в секунду

Часто вас интересует пропускная способность — количество операций в секунду. Пакет benchmark-ips сообщает это значение, но его можно приблизительно вычислить вручную.

  • Подсчитайте итерации за фиксированный промежуток времени
  • Большее значение ips означает более высокую скорость
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 0.2
count = 0
while Process.clock_gettime(Process::CLOCK_MONOTONIC) < deadline
  count += 1
  'hello'.upcase
end
puts "Iterations in 0.2s: #{count}"

Управление сборщиком мусора

Сборщик мусора может исказить результаты. Вы можете временно отключить его, чтобы получить более стабильные значения.

  • Вызовите GC.disable перед измерением, а GC.enable — после
  • Используйте это осторожно, чтобы избежать роста потребления памяти
require 'benchmark'

GC.disable
t = Benchmark.realtime { 100_000.times { |i| i.to_s } }
GC.enable
puts "Without GC: #{t.round(4)}s"

Усреднение нескольких запусков

Запустите тест несколько раз и усредните результаты, чтобы сгладить разброс.

  • При необходимости отбросьте самый медленный выброс
  • Для стабильности сообщайте медиану
require 'benchmark'

times = 3.times.map do
  Benchmark.realtime { (1..50_000).map { |n| n * n } }
end
avg = times.sum / times.size
puts "Average: #{avg.round(4)}s"

Проверка

Проверьте свои знания о тестировании производительности.

Повторение

Вы научились измерять производительность:

  • Модуль Benchmark точно измеряет время выполнения кода
  • realtime, measure, bm и bmbm предназначены для разных задач
  • Для точного измерения времени используйте монотонные часы
  • Избегайте вводящих в заблуждение микроизмерений и учитывайте работу сборщика мусора
  • Усредняйте несколько запусков, чтобы уменьшить шум

Далее вы воспользуетесь специализированными инструментами профилирования.

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

Урок «Измерение производительности» бесплатный?

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

Чему я научусь в уроке «Измерение производительности»?

Модуль Benchmark Ты практикуешь Ruby Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

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

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

Сколько времени занимает урок «Измерение производительности»?

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

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

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

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

  1. Измерение производительности
  2. Инструменты профилирования
  3. Оптимизация памяти
  4. Распространённые узкие места
← Назад к Ruby Academy