שיעורי מודול (3/5)
מדדים ופרופילים
בנוסף לבדיקות פונקציונליות, ל-go test יש גם בנצ'מרקים מובנים (BenchmarkXxx) ותומך בפרופילי CPU וזיכרון (pprof). הכל ללא תלות חיצונית.
צורה של אמת מידה
func BenchmarkSum(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = Sum(2, 3)
}
}מאפיינים:
- חתימה מדויקת:
func BenchmarkXxx(b *testing.B). - הלולאה חייבת להפעיל
b.Nאיטרציות: המסגרת מתאימה אתb.Nאוטומטית, מתחילה ב-1 וגדלה עד שהמדידה מתייצבת (כ-1 שנייה כברירת מחדל). - התוצאה היא
ns/op(ננו-שניות לכל פעולה) ועם-benchmem, גםB/opוallocs/op.
פקודות אופייניות
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פלט אופייני:
BenchmarkSum-8 1000000000 0.31 ns/op
-8 הוא הערך GOMAXPROCS. 0.31 ns/op הוא הזמן הממוצע לשיחה.
הגדרה יקרה: b.ResetTimer
אם יש לך שלב הכנה ארוך לפני הלולאה, אל תכלול אותו מהמדידה:
func BenchmarkSearch(b *testing.B) {
data := buildLargeSlice(1_000_000) // expensive
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = Search(data, 42)
}
}גרסאות שימושיות:
b.StopTimer()/b.StartTimer()- השהה את המדידה סביב שלב לא מעניין (שימושי בתוך הלולאה).b.ReportAllocs()- לכפות דיווח על הקצאה גם ללא-benchmem.
טבלת בנצ'מרק עם b.Run
בדיוק כמו t.Run עבור בדיקות, יש b.Run עבור אמות מידה פרמטריות:
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, ",")
}
})
}
}פלט שורות כמו BenchmarkSplit/n=10-8, BenchmarkSplit/n=1000-8, ... אידיאלי עבור הרחבת תרשימים.
השוואת שני יישומים עם benchstat
go test -bench=. -count=10 > old.txt
# apply change
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txtbenchstat (ב-golang.org/x/perf/cmd/benchstat) מחשב את הממוצע, סטיית התקן והמובהקות הסטטיסטית של ההפרש.
תרגילים
הגדר BenchmarkSum עם הלולאה מעל b.N שקוראת Sum(2, 3).
הפתרון זמין לאחר 3 ניסיונות
הוסף את b.ResetTimer אחרי ההגדרה היקרה, לפני הלולאה, כך שההגדרה לא תיכלל במדידה.
הפתרון זמין לאחר 3 ניסיונות
איזה דגל מריץ את כל המדדים בחבילה?
$ go test ???