Ce face testing.B
Un benchmark este o funcție func BenchmarkXxx(b *testing.B) într-un fișier _test.go. Nu rulează la go test obișnuit, ci doar cu go test -bench=. (sau un model în loc de punct). Go repetă codul de câte ori e nevoie ca măsurătoarea să fie stabilă și raportează timpul mediu pe operație (ns/op).
Bucla de măsurare se scrie cu for b.Loop() { ... } (Go 1.24). Forma veche, for i := 0; i < b.N; i++ { ... }, se găsește în mult cod existent. Cu -benchmem sau b.ReportAllocs() vezi și memoria alocată pe operație. testing.B are și metodele lui testing.T (Error, Fatal, Log, Run).
Rezultatele depind de calculator; compară doar măsurători făcute pe aceeași mașină. Unealta benchstat compară statistic două rulări.
Parametri
| Parametru | Descriere |
|---|---|
b |
Valoarea primită de benchmark. |
Ce returnează
Nu se aplică (este un tip).
Exemple
Exemplul 1: Concatenare cu + față de strings.Builder
// fișierul text_test.go
package magazin
import (
"strings"
"testing"
)
var produse = strings.Fields("pâine lapte ouă unt brânză mere pere cafea ceai zahăr")
func BenchmarkPlus(b *testing.B) {
for b.Loop() {
s := ""
for _, p := range produse {
s += p + ", "
}
}
}
func BenchmarkBuilder(b *testing.B) {
for b.Loop() {
var sb strings.Builder
for _, p := range produse {
sb.WriteString(p)
sb.WriteString(", ")
}
_ = sb.String()
}
}
Rezultatul în terminal, pe un Mac cu procesor Apple (numerele diferă de la un calculator la altul)
$ go test -bench=. -benchmem
goos: darwin
goarch: arm64
pkg: magazin
cpu: Apple M1 Pro
BenchmarkPlus-10 3921576 306.5 ns/op 432 B/op 10 allocs/op
BenchmarkBuilder-10 8212881 144.3 ns/op 248 B/op 5 allocs/op
PASS
ok magazin 2.621s
Exemplul 2: Un benchmark rulat din main cu testing.Benchmark
testing.Benchmark rulează un benchmark dintr-un program obișnuit. Timpul diferă la fiecare rulare, așa că afișăm doar dacă măsurătoarea s-a făcut.
package main
import (
"fmt"
"strings"
"testing"
)
func main() {
r := testing.Benchmark(func(b *testing.B) {
for b.Loop() {
strings.Repeat("Iași ", 100)
}
})
fmt.Println("a rulat de mai multe ori:", r.N > 1)
fmt.Println("timp pe operație măsurat:", r.NsPerOp() > 0)
}
Rezultat
a rulat de mai multe ori: true
timp pe operație măsurat: true
Greșeli frecvente
- Rulezi
go testși te miri că benchmark-urile nu apar. Adaugă-bench=.. - Tragi concluzii dintr-o singură rulare sau compari rezultate de pe calculatoare diferite. Rulează de mai multe ori (
-count=10) și compară cubenchstat.
Comenzi înrudite
testing.B.Loop: Condiția buclei unui benchmark: returnează true cât timp mai trebuie repetat codul măsurat (Go 1.24).testing.B.ResetTimer: Pune la zero timpul și alocările măsurate până acum, ca pregătirea costisitoare să nu intre în rezultat.testing.T: Tipul primit de fiecare funcție de test; prin el raportezi erori, scrii mesaje și controlezi testul.