Пакет runtime/pprof
Пакет runtime/pprof предоставляет возможность профилирования Go-приложений,
собирая данные о производительности во время выполнения тестов. Он позволяет
записывать профили процессора, памяти, блокировок и других ресурсов,
что помогает выявлять узкие места и оптимизировать код. Основные функции
пакета: StartCPUProfile для начала сбора профиля процессора,
StopCPUProfile для остановки сбора, WriteHeapProfile для
записи профиля кучи, а также Lookup для получения других типов профилей.
Сбор профиля процессора
Для сбора профиля процессора используется функция StartCPUProfile,
которая принимает io.Writer для записи данных. Завершать сбор
следует функцией StopCPUProfile. Рассмотрим пример использования
в тестовом окружении:
package main
import (
"os"
"runtime/pprof"
)
func main() {
f, err := os.Create("cpu.prof")
if err != nil {
panic(err)
}
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// выполняем нагрузочный код
for i := 0; i < 1000000; i++ {
_ = i * i
}
}
Результат выполнения кода:
"cpu.prof file created"
После выполнения программы файл cpu.prof можно проанализировать
с помощью команды go tool pprof.
Сбор профиля кучи
Для записи профиля кучи используется функция WriteHeapProfile,
которая записывает текущий снимок распределения памяти. Это полезно для
выявления утечек памяти и оптимизации использования ресурсов:
package main
import (
"os"
"runtime/pprof"
)
func main() {
f, err := os.Create("heap.prof")
if err != nil {
panic(err)
}
defer f.Close()
// выделяем память
data := make([]byte, 1000000)
for i := range data {
data[i] = byte(i % 256)
}
err = pprof.WriteHeapProfile(f)
if err != nil {
panic(err)
}
}
Результат выполнения кода:
"heap.prof file created"
Функция WriteHeapProfile записывает данные о текущем состоянии
кучи, включая количество выделенной памяти и количество объектов.
Использование Lookup
Функция Lookup возвращает профиль по его имени. Поддерживаются
профили: "goroutine", "heap", "threadcreate", "block", "mutex". Это
позволяет получить детальную информацию о различных аспектах работы
программы:
package main
import (
"fmt"
"os"
"runtime/pprof"
)
func main() {
prof := pprof.Lookup("goroutine")
if prof == nil {
fmt.Println("profile not found")
return
}
f, err := os.Create("goroutine.prof")
if err != nil {
panic(err)
}
defer f.Close()
err = prof.WriteTo(f, 0)
if err != nil {
panic(err)
}
fmt.Println("goroutine profile saved")
}
Результат выполнения кода:
"goroutine profile saved"
В примере мы получаем профиль горутин и сохраняем его в файл для последующего анализа.
Использование в тестах с бенчмарками
Пакет runtime/pprof часто используется вместе с бенчмарками для
детального анализа производительности. Запустим бенчмарк с профилированием:
package main
import (
"os"
"runtime/pprof"
"testing"
)
func BenchmarkExample(b *testing.B) {
f, err := os.Create("bench.cpu.prof")
if err != nil {
b.Fatal(err)
}
defer f.Close()
err = pprof.StartCPUProfile(f)
if err != nil {
b.Fatal(err)
}
defer pprof.StopCPUProfile()
for i := 0; i < b.N; i++ {
_ = i * i
}
}
Результат выполнения кода:
"bench.cpu.prof file created"
Этот подход позволяет собирать профили непосредственно во время выполнения бенчмарков, что дает точную информацию о производительности конкретных участков кода.
Смотрите также
-
функцию
testing.B,
которая используется для написания бенчмарков -
функцию
benchmark,
которая описывает процесс бенчмаркинга в Go -
функцию
testing.T,
которая используется для написания обычных тестов -
функцию
pprof.StartCPUProfile,
которая запускает сбор профиля процессора