Написание тестов производительности с testing.B
BenchmarkXxx, цикл b.N и флаг -bench
«Написание тестов производительности с testing.B» — бесплатный урок Go Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Сигнатура функции Benchmark
Функции Benchmark начинаются с Benchmark и принимают *testing.B. Они находятся в файле _test.go вместе с обычными тестами.
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}b.N
Средство тестирования автоматически изменяет значение b.N — количество итераций цикла, — пока выполнение Benchmark не займёт хотя бы 1 секунду. Это позволяет получить стабильное значение наносекунд на операцию.
Запуск Benchmark
Функции Benchmark не запускаются одной командой go test. Используйте флаг -bench, чтобы включить их:
go test -bench=. -benchmem ./...
// BenchmarkAdd-8 500000000 2.13 ns/op 0 B/op 0 allocs/opФлаг -benchmem
-benchmem добавляет статистику выделения памяти: количество байтов на операцию и число выделений на операцию. Большое количество выделений часто указывает на проблемы с производительностью.
b.ResetTimer
Вызовите b.ResetTimer() после затратной настройки, которую не следует учитывать в Benchmark:
func BenchmarkQuery(b *testing.B) {
db := setupDB() // expensive
b.ResetTimer()
for i := 0; i < b.N; i++ {
db.Query("SELECT 1")
}
}b.StopTimer / b.StartTimer
Приостановите и возобновите таймер вокруг настройки или очистки, которые не должны учитываться во времени Benchmark.
for i := 0; i < b.N; i++ {
b.StopTimer()
data := generateInput()
b.StartTimer()
process(data)
}b.SetBytes
Вызовите b.SetBytes(n), чтобы дополнительно сообщить пропускную способность (байт/с) наряду со временем на операцию. Это полезно для Benchmark сериализации или сетевого кода.
b.SetBytes(int64(len(payload)))
for i := 0; i < b.N; i++ {
encode(payload)
}Сравнение Benchmark
Используйте benchstat, чтобы сравнить два запуска Benchmark и выявить статистически значимые различия:
go test -bench=. -count=10 > before.txt
# make change
go test -bench=. -count=10 > after.txt
benchstat before.txt after.txtПредотвращение удаления неиспользуемого кода
Присвойте результат переменной уровня пакета или переменной-приёмнику, чтобы компилятор не оптимизировал код, измеряемый Benchmark, и не удалил его:
var result int
func BenchmarkFib(b *testing.B) {
for i := 0; i < b.N; i++ {
result = Fib(20)
}
}Вложенные Benchmark
Используйте b.Run, чтобы создавать именованные вложенные Benchmark, подобно табличным тестам:
for _, size := range []int{10, 100, 1000} {
b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
for i := 0; i < b.N; i++ { sort(make([]int, size)) }
})
}Benchmark и профилирование
Benchmark количественно оценивает производительность. Профилирование (pprof) показывает, на что расходуется время. Используйте Benchmark для измерений, а профилирование — чтобы определить, что именно нужно оптимизировать.
Быстрая проверка
Почему тело цикла Benchmark должно использовать результат, чтобы предотвратить оптимизацию компилятором?
Итоги: Benchmark
Основные положения:
- BenchmarkXxx(b *testing.B) с циклом for i := 0; i < b.N; i++
- go test -bench=. -benchmem для статистики выделения памяти
- b.ResetTimer() после затратной настройки
- Используйте benchstat для сравнения запусков; присваивайте результаты, чтобы предотвратить удаление кода
Часто задаваемые вопросы
Урок «Написание тестов производительности с testing.B» бесплатный?
Да — полный текст урока «Написание тестов производительности с testing.B» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Написание тестов производительности с testing.B»?
BenchmarkXxx, цикл b.N и флаг -bench Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Написание тестов производительности с testing.B»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Написание тестов производительности с testing.B
- Профилирование CPU с pprof
- Профилирование кучи и выделения памяти
- Трассировка выполнения