Bài học theo mô-đun (3/5)
Điểm chuẩn và hồ sơ
Ngoài các kiểm tra chức năng, go test còn có điểm chuẩn (BenchmarkXxx) tích hợp sẵn và hỗ trợ cấu hình CPU và bộ nhớ (pprof). Tất cả không có sự phụ thuộc bên ngoài.
Hình dạng của điểm chuẩn
func BenchmarkSum(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Sum(2, 3)
}
}Đặc trưng:
- Chữ ký chính xác:
func BenchmarkXxx(b *testing.B). - Vòng lặp phải chạy
b.Nvòng lặp: khung tự động điều chỉnhb.N, bắt đầu từ 1 và tăng dần cho đến khi số đo ổn định (~1 giây theo mặc định). - Kết quả là
ns/op(nano giây cho mỗi thao tác) và, với-benchmem, cũng nhưB/opvàallocs/op.
Các lệnh điển hình
go test -bench=. ./... # all benchmarks
go test -bench=Sum -benchmem # only Sum, with memory info
go test -bench=. -benchtime=5s # each benchmark for 5 seconds
go test -bench=. -cpuprofile=cpu.out # generate a CPU profileĐầu ra điển hình:
BenchmarkSum-8 1000000000 0.31 ns/op
-8 là giá trị GOMAXPROCS. 0.31 ns/op là thời gian trung bình cho mỗi cuộc gọi.
Thiết lập đắt tiền: b.ResetTimer
Nếu bạn có một bước chuẩn bị dài trước vòng lặp, hãy loại nó khỏi phép đo:
func BenchmarkSearch(b *testing.B) {
data := buildLargeSlice(1_000_000) // expensive
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = Search(data, 42)
}
}Các biến thể hữu ích:
b.StopTimer()/b.StartTimer()— tạm dừng phép đo xung quanh một giai đoạn không thú vị (tiện dụng trong vòng lặp).b.ReportAllocs()— buộc phải báo cáo phân bổ ngay cả khi không có-benchmem.
Bảng điểm chuẩn với b.Run
Giống như t.Run dành cho kiểm tra, có b.Run dành cho điểm chuẩn tham số:
func BenchmarkSplit(b *testing.B) {
for _, size := range []int{10, 1000, 100000} {
b.Run(fmt.Sprintf("n=%d", size), func(b *testing.B) {
s := strings.Repeat("a,", size)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = strings.Split(s, ",")
}
})
}
}Các hàng xuất ra như BenchmarkSplit/n=10-8, BenchmarkSplit/n=1000-8, ... lý tưởng cho biểu đồ tỷ lệ.
So sánh hai cách triển khai với benchstat
go test -bench=. -count=10 > old.txt
# apply change
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txtbenchstat (trong golang.org/x/perf/cmd/benchstat) tính giá trị trung bình, độ lệch chuẩn và ý nghĩa thống kê của chênh lệch.
Bài tập
Xác định BenchmarkSum bằng vòng lặp trên b.N gọi Sum(2, 3).
Giải pháp khả dụng sau 3 lần thử
Thêm b.ResetTimer SAU thiết lập đắt tiền, trước vòng lặp, để thiết lập không được đưa vào phép đo.
Giải pháp khả dụng sau 3 lần thử
Cờ nào chạy tất cả các điểm chuẩn trong gói?
$ go test ???