0Pricing
Go Academy · Урок

Написание тестов производительности с 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 — локальная установка не требуется.

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

  1. Написание тестов производительности с testing.B
  2. Профилирование CPU с pprof
  3. Профилирование кучи и выделения памяти
  4. Трассировка выполнения
← Назад к Go Academy