Метод testing.B.ResetTimer
Метод testing.B.ResetTimer сбрасывает таймер бенчмарка,
обнуляя время выполнения и количество операций. Он используется
для исключения из измерений времени, затраченного на подготовительные
операции, такие как инициализация данных или настройка окружения.
Метод вызывается внутри бенчмарк-функции перед основным циклом
измерения производительности.
Синтаксис
b.ResetTimer()
Метод не принимает параметров и не возвращает значений.
Он доступен только в бенчмарк-функциях, которые принимают
указатель на testing.B.
Пример
Рассмотрим бенчмарк, который измеряет производительность
функции сложения чисел. В подготовительной части создается
слайс чисел. Чтобы исключить время на создание слайса,
используем ResetTimer:
package main
import (
"testing"
)
func sum(numbers []int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func BenchmarkSum(b *testing.B) {
// Подготовительная операция
numbers := make([]int, 1000)
for i := range numbers {
numbers[i] = i
}
// Сброс таймера перед основным циклом
b.ResetTimer()
for i := 0; i < b.N; i++ {
sum(numbers)
}
}
В этом примере время на создание и заполнение слайса не будет учтено в результате бенчмарка.
Пример с разными подготовительными операциями
Покажем, как ResetTimer влияет на результат
при выполнении сложных подготовительных операций.
Бенчмарк измеряет производительность поиска в карте:
package main
import (
"strconv"
"testing"
)
func BenchmarkMapLookup(b *testing.B) {
// Подготовка большой карты
m := make(map[string]int)
for i := 0; i < 10000; i++ {
m[strconv.Itoa(i)] = i
}
// Сброс таймера после подготовки
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = m["5000"]
}
}
Без вызова ResetTimer время на создание карты
из 10000 элементов исказило бы результаты измерения
производительности поиска.
Пример сравнения с и без ResetTimer
Рассмотрим пример, демонстрирующий разницу в результатах
с использованием ResetTimer и без него.
Бенчмарк измеряет операцию конкатенации строк:
package main
import (
"strings"
"testing"
)
func concatStrings(count int) string {
var builder strings.Builder
for i := 0; i < count; i++ {
builder.WriteString("a")
}
return builder.String()
}
func BenchmarkConcat(b *testing.B) {
// Подготовка выполняется перед циклом
count := 100
// Сброс таймера
b.ResetTimer()
for i := 0; i < b.N; i++ {
concatStrings(count)
}
}
func BenchmarkConcatWithoutReset(b *testing.B) {
// Подготовка внутри цикла - время учитывается
for i := 0; i < b.N; i++ {
count := 100
concatStrings(count)
}
}
В первом бенчмарке время на инициализацию переменной
count исключено из измерений. Во втором случае
это время учитывается, что может дать менее точные
результаты.
Особенности использования
Метод ResetTimer следует вызывать после всех
подготовительных операций, но до начала основного цикла
измерения. Он особенно полезен, когда подготовка требует
значительных временных затрат, например, при чтении
данных из файлов, создании сложных структур или
выполнении сетевых запросов.
Важно помнить, что ResetTimer сбрасывает не только
время, но и количество операций. Поэтому его следует
вызывать только один раз за выполнение бенчмарк-функции.
Смотрите также
-
метод
testing.B.StartTimer,
который возобновляет измерение времени после остановки -
метод
testing.B.StopTimer,
который останавливает измерение времени бенчмарка -
поле
testing.B.N,
которое определяет количество итераций бенчмарка -
метод
testing.B.ReportAllocs,
который включает отчет о выделениях памяти