Функция BenchmarkXxx
BenchmarkXxx - это не самостоятельная функция, а шаблон именования функций бенчмарков в пакете testing. Бенчмарки используются для измерения производительности кода: времени выполнения, количества операций и аллокаций памяти. Функция бенчмарка принимает указатель на testing.B и должна выполняться b.N раз для получения достоверных результатов.
Соглашение об именовании требует, чтобы имя функции бенчмарка начиналось с префикса Benchmark, за которым следует произвольная часть, описывающая тестируемый код. Например, BenchmarkConcat, BenchmarkSortInts или BenchmarkStringBuilder. Функция должна быть экспортируемой (начинаться с заглавной буквы) и иметь сигнатуру func BenchmarkXxx(b *testing.B).
Синтаксис
func BenchmarkXxx(b *testing.B) {
for i := 0; i < b.N; i++ {
// код, производительность которого измеряется
}
}
Внутри тела бенчмарка цикл for с условием i < b.N является обязательным. Именно внутри этого цикла размещается тестируемый код. Поле b.N автоматически подбирается рантаймом для стабильных результатов.
Пример 1
Давайте создадим бенчмарк для сравнения конкатенации строк через оператор +:
package main
import (
"testing"
)
func BenchmarkConcat(b *testing.B) {
for i := 0; i < b.N; i++ {
s := "Hello" + " " + "World"
_ = s
}
}
Запуск бенчмарка выполняется командой go test -bench=:
"go test -bench=BenchmarkConcat"
Результат выполнения бенчмарка:
"BenchmarkConcat-8 1000000000 0.0000009 ns/op"
В выводе мы видим: имя бенчмарка с указанием числа ядер процессора (-8), количество итераций (1000000000) и среднее время на одну операцию (0.0000009 ns/op).
Пример 2
Рассмотрим бенчмарк, который использует b.ResetTimer() для сброса таймера после подготовительных операций:
package main
import (
"strings"
"testing"
)
func BenchmarkBuilder(b *testing.B) {
var sb strings.Builder
b.ResetTimer()
for i := 0; i < b.N; i++ {
sb.WriteString("Hello")
}
}
Результат выполнения бенчмарка:
"BenchmarkBuilder-8 30000000 45.2 ns/op"
Метод b.ResetTimer() позволяет исключить время на подготовку данных, измеряя только производительность тестируемого кода.
Пример 3
Используем b.ReportAllocs() для отображения информации о выделении памяти в бенчмарке:
package main
import (
"testing"
)
func BenchmarkAlloc(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
s := make([]int, 10, 20)
_ = s
}
}
Результат выполнения бенчмарка с аллокациями:
"BenchmarkAlloc-8 50000000 24.8 ns/op 128 B/op 1 allocs/op"
В выводе добавились два столбца: выделенная память на операцию (128 B/op) и количество аллокаций (1 allocs/op).
Смотрите также
-
тип
testing.B,
который предоставляет методы для управления бенчмарками -
метод
testing.B.N,
который определяет количество итераций в бенчмарке -
метод
testing.B.ResetTimer,
который сбрасывает таймер бенчмарка -
метод
testing.B.ReportAllocs,
который включает отчет по аллокациям памяти