Pelajaran modul (3/5)
Tolok ukur dan profil
Selain pengujian fungsional, go test juga memiliki benchmark bawaan (BenchmarkXxx) dan mendukung profil CPU dan memori (pprof). Semua tanpa ketergantungan eksternal.
Bentuk patokan
func BenchmarkSum(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Sum(2, 3)
}
}Karakteristik:
- Tanda tangan persisnya:
func BenchmarkXxx(b *testing.B). - Perulangan harus menjalankan iterasi
b.N: kerangka kerja menyesuaikanb.Nsecara otomatis, dimulai dari 1 dan terus bertambah hingga pengukuran stabil (~1 detik secara default). - Hasilnya adalah
ns/op(nanodetik per operasi) dan, dengan-benchmem, jugaB/opdanallocs/op.
Perintah yang khas
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 profileKeluaran tipikal:
BenchmarkSum-8 1000000000 0.31 ns/op
-8 adalah nilai GOMAXPROCS. 0.31 ns/op adalah waktu rata-rata per panggilan.
Penyiapan mahal: b.ResetTimer
Jika Anda memiliki langkah persiapan yang panjang sebelum loop, kecualikan dari pengukuran:
func BenchmarkSearch(b *testing.B) {
data := buildLargeSlice(1_000_000) // expensive
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = Search(data, 42)
}
}Varian yang berguna:
b.StopTimer()/b.StartTimer()— menjeda pengukuran di sekitar fase yang tidak menarik (berguna di dalam loop).b.ReportAllocs()— pelaporan alokasi kekuatan bahkan tanpa-benchmem.
Tabel tolok ukur dengan b.Run
Sama seperti t.Run untuk pengujian, ada b.Run untuk tolok ukur parametrik:
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, ",")
}
})
}
}Baris keluaran seperti BenchmarkSplit/n=10-8, BenchmarkSplit/n=1000-8, ... ideal untuk menskalakan grafik.
Membandingkan dua implementasi dengan benchstat
go test -bench=. -count=10 > old.txt
# apply change
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txtbenchstat (dalam golang.org/x/perf/cmd/benchstat) menghitung mean, deviasi standar, dan signifikansi statistik dari perbedaan tersebut.
Latihan
Definisikan BenchmarkSum dengan loop di atas b.N yang memanggil Sum(2, 3).
Solusi tersedia setelah 3 upaya
Tambahkan b.ResetTimer SETELAH pengaturan yang mahal, sebelum loop, sehingga pengaturan tidak termasuk dalam pengukuran.
Solusi tersedia setelah 3 upaya
Bendera manakah yang menjalankan semua tolok ukur dalam paket?
$ go test ???