Chuyển đến nội dung chính
Mô-đun 9 · Bài học 3 trong tổng số 543/50 trong khóa học~12 min
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

Go
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.N vòng lặp: khung tự động điều chỉnh b.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/op và allocs/op.

Các lệnh điển hình

Bash
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:

Code
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:

Go
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ố:

Go
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

Bash
go test -bench=. -count=10 > old.txt
# apply change
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txt

benchstat (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

tập thể dục#go.m9.l3.e1
Nỗ lực: 0Đang tải…

Xác định BenchmarkSum bằng vòng lặp trên b.N gọi Sum(2, 3).

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m9.l3.e2
Nỗ lực: 0Đang tải…

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.

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m9.l3.e3
Sẵn sàng

Cờ nào chạy tất cả các điểm chuẩn trong gói?

Go
$ go test ???
Tùy chọn trả lời