Ответ
Да, *testing.B
— это ключевой элемент для написания бенчмарков (тестов производительности) в Go. Он передается в качестве аргумента в функции, имя которых начинается с Benchmark
.
Основные поля и методы *testing.B
:
b.N
— количество итераций, которое бенчмарк-фреймворк определяет автоматически, чтобы тест выполнялся значимое время (обычно около 1 секунды).b.ResetTimer()
— сбрасывает таймер. Используется, чтобы исключить из замеров время на подготовительные операции.b.StopTimer()
/b.StartTimer()
— позволяют временно останавливать и возобновлять замер времени внутри цикла.
Пример бенчмарка:
package main
import "testing"
// Тестируемая функция
func Sum(a, b int) int {
return a + b
}
// Глобальная переменная для предотвращения оптимизации компилятора
var result int
func BenchmarkSum(b *testing.B) {
var r int
// Цикл выполняется b.N раз
for i := 0; i < b.N; i++ {
// Записываем результат, чтобы компилятор не удалил вызов Sum
r = Sum(1, 2)
}
// Присваиваем результат глобальной переменной
result = r
}
Запуск и анализ:
Бенчмарки запускаются командой go test
с флагом -bench
.
# Запустить все бенчмарки в пакете и показать выделение памяти
go test -bench=. -benchmem
Вывод будет выглядеть примерно так:
BenchmarkSum-8 1000000000 0.25 ns/op 0 B/op 0 allocs/op
Это означает, что функция Sum
выполнялась 1 миллиард раз, и каждая операция в среднем занимала 0.25 наносекунды, не выделяя дополнительной памяти.
Важно присваивать результат вызова тестируемой функции переменной, чтобы компилятор не счел этот вызов "мертвым кодом" (dead code) и не удалил его, что привело бы к некорректным результатам бенчмарка.