[Golang]Эталонный тест производительности

задняя часть Go

предисловие

Бенчмаркинг предназначен для измерения производительности программы при фиксированной рабочей нагрузке, а язык Go также обеспечивает поддержку эталонного тестирования производительности.benchmark.

инструкции

Вот пример кода для эталонного теста, чтобы понять, как он используется:

func Benchmark_test(b *testing.B) {
	for i := 0; i < b.N ; i++ {
		s := make([]int, 0)
		for i := 0; i < 10000; i++ {
			s = append(s, i)
		}
	}
}
  • Файл для бенчмаркинга должен начинаться с*_test.goФайл заканчивается на , это то же самое, что и суффикс имени тестового файла, напримерabc_test.go
  • Методы для участия в тесте Benchmark должны начинаться сBenchmarkпрефикс, напримерBenchmarkABC()
  • Участвующие функции тестирования должны принимать указатель наBenchmarkуказатель типа как единственный параметр,*testing.B
  • Функция Benchmark не возвращает значение
  • b.ResetTimerЭто сброс таймера.Когда он вызывается, это означает перезапуск времени.Некоторые приготовления в тестовой функции можно игнорировать.
  • b.NОн предоставляется платформой бенчмаркинга и представляет собой количество циклов, поскольку тестовый код необходимо вызывать неоднократно, прежде чем можно будет оценить производительность.

Команды и параметры

Команда проверки производительностиgo test [参数],Напримерgo test -bench=. -benchmem, параметры и значения конкретных команд следующие:

параметр значение
-bench regexp Тестирование производительности, поддерживающее выражения для фильтрации тестовых функций.
-bench . заключается в тестировании всех тестовых функций, и указанное имя будет выполнять только конкретный метод тестирования, а не все
-benchmem Отображать статистику выделения памяти тестовой функции при тестировании производительности
-счет н Сколько запускать тесты и производительность, по умолчанию один раз
-run regexp Запускайте только определенные тестовые функции, например -run ABC, чтобы тестировать только те тестовые функции, которые содержат ABC в имени функции.
-timeout t Если время теста превышает t, паника, по умолчанию 10 минут.
-v Отображение подробной информации о тесте, а также отображение журналов методов Log и Logf.

Результаты теста

После выполнения команды результаты теста производительности отображаются следующим образом.

$ go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: program/benchmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Benchmark_test-12        7439091               152.0 ns/op           248 B/op          5 allocs/op
PASS
ok      promgram/benchmark    1.304s

Проанализируйте приведенные выше результаты один за другим:

элемент результата значение
Benchmark_test-12 Benchmark_testимя тестовой функции-12Указывает, что значение GOMAXPROCS (количество потоков) равно 12.
7439091 Указывает, что всего7439091раз, а именноb.Nзначение
152.0 ns/op Указывает среднюю стоимость операции152,0 нс
248B/op Указывает, что каждая операция применяется248Byteзапрос памяти
5 allocs/op Указывает, что каждая операция применяется5Вторичная память

Пример сравнения производительности

следующее черезстрока числового преобразованияПримеры используются для сравнения и анализа результатов теста производительности.

//Sprintf
func BenchmarkSprintf(b *testing.B) {
	num := 10
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		fmt.Sprintf("%d", num)
	}
}

//Format
func BenchmarkFormat(b *testing.B) {
	num := int64(10)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		strconv.FormatInt(num, 10)
	}
}

//Itoa
func BenchmarkItoa(b *testing.B) {
	num := 10
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		strconv.Itoa(num)
	}
}

Выполните команду нижеgo test -bench=. -benchmem, полученный отчет об испытаниях выглядит следующим образом:

%  go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: program/benchmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkSprintf-12     16364854                63.70 ns/op            2 B/op          1 allocs/op
BenchmarkFormat-12      493325650                2.380 ns/op           0 B/op          0 allocs/op
BenchmarkItoa-12        481683436                2.503 ns/op           0 B/op          0 allocs/op
PASS
ok      program/benchmark    4.007s

Его можно найти,BenchmarkSprintfМетод занимает больше всего времени,BenchmarkFormatсамый быстрый,BenchmarkItoaТоже очень быстро. Разница в том,fmt.Sprintf()Выделение памяти было сделано во время выполнения1 allocs/op.

В сочетании с анализом pprof

параметр значение Пример команды
-cpuprofile [file] выходной файл производительности процессора go test -bench=. -benchmem -cpuprofile=cpu.out
-memprofile [file] выходной файл производительности памяти памяти go test -bench=. -benchmem -memprofile=cpu.out

Сгенерированопроцессор, памятьдоступ к файлам возможен черезgo tool pprof [file]просмотреть, а затем передать в pproflist [file]вид методапроцессор, памятькропотливый

### 内存情况
(pprof) list BenchmarkArrayAppend
Total: 36.49GB
ROUTINE ======================== program/benchmark.BenchmarkArrayAppend in /Users/guanjian/workspace/go/program/benchmark/benchmark_test.go
   11.98GB    11.98GB (flat, cum) 32.83% of Total
         .          .      7://Array
         .          .      8:func BenchmarkArrayAppend(b *testing.B) {
         .          .      9:   for i := 0; i < b.N; i++ {
         .          .     10:           var arr []int
         .          .     11:           for i := 0; i < 10000; i++ {
   11.98GB    11.98GB     12:                   arr = append(arr, i)
         .          .     13:           }
         .          .     14:   }
         .          .     15:}
## CPU情况
(pprof) list BenchmarkArrayAppend
Total: 8.86s
ROUTINE ======================== program/benchmark.BenchmarkArrayAppend in /Users/guanjian/workspace/go/program/benchmark/benchmark_test.go
      10ms      640ms (flat, cum)  7.22% of Total
         .          .      6:
         .          .      7://Array
         .          .      8:func BenchmarkArrayAppend(b *testing.B) {
         .          .      9:   for i := 0; i < b.N; i++ {
         .          .     10:           var arr []int
      10ms       10ms     11:           for i := 0; i < 10000; i++ {
         .      630ms     12:                   arr = append(arr, i)
         .          .     13:           }
         .          .     14:   }
         .          .     15:}

Суммировать

go предоставляет инструменты для эталонного тестирования производительности, обеспечивает анализ отчетов об использовании памяти, ЦП и т. д., а также может использовать pprof для получения более качественных аналитических отчетов и т. д. Если вам нужен углубленный анализ, вы также можете использовать ранее введенный gdb для трассировка нижнего слоя кода и декомпиляция кода, чтобы увидеть конкретную потерю производительности.

Ссылаться на

перейти к эталонному тестированию производительности модульный тест эталонный тест использовать подробно
пройти тест производительности