دروس الوحدة (3/5)
المعايير والملفات الشخصية
بالإضافة إلى الاختبارات الوظيفية، يحتوي go test أيضًا على مقاييس أداء (BenchmarkXxx) ويدعم ملفات تعريف وحدة المعالجة المركزية والذاكرة (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 ويتزايد حتى يستقر القياس (~ ثانية واحدة افتراضيًا). - النتيجة هي
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 ???