From 6fb38bdee17208f9e2f933614eb6d9052095be22 Mon Sep 17 00:00:00 2001 From: Easwar Swaminathan Date: Wed, 21 Aug 2019 15:24:29 -0700 Subject: [PATCH] Fix a bug in benchmark code. (#2989) Total number of Allocs and AllocedBytes retrieved from runtime.Memstats() were not being divided by the number of completed operations during the benchmark run, to get the correct number of Allocs/op and Bytes/op. --- benchmark/benchresult/main.go | 24 ++++++++++++++---------- benchmark/stats/stats.go | 12 ++++++------ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/benchmark/benchresult/main.go b/benchmark/benchresult/main.go index ec27a830..2dab58ca 100644 --- a/benchmark/benchresult/main.go +++ b/benchmark/benchresult/main.go @@ -76,8 +76,8 @@ func compareTwoMap(m1, m2 map[string]stats.BenchResults) { changes += intChange("TotalOps", v1.Data.TotalOps, v2.Data.TotalOps) changes += intChange("SendOps", v1.Data.SendOps, v2.Data.SendOps) changes += intChange("RecvOps", v1.Data.RecvOps, v2.Data.RecvOps) - changes += intChange("Bytes/op", v1.Data.AllocedBytes, v2.Data.AllocedBytes) - changes += intChange("Allocs/op", v1.Data.Allocs, v2.Data.Allocs) + changes += floatChange("Bytes/op", v1.Data.AllocedBytes, v2.Data.AllocedBytes) + changes += floatChange("Allocs/op", v1.Data.Allocs, v2.Data.Allocs) changes += floatChange("ReqT/op", v1.Data.ReqT, v2.Data.ReqT) changes += floatChange("RespT/op", v1.Data.RespT, v2.Data.RespT) changes += timeChange("50th-Lat", v1.Data.Fiftieth, v2.Data.Fiftieth) @@ -93,9 +93,16 @@ func compareBenchmark(file1, file2 string) { compareTwoMap(createMap(file1), createMap(file2)) } -func printline(benchName, total, send, recv, allocB, allocN, reqT, respT, ltc50, ltc90, l99, lAvg interface{}) { - fmt.Printf("%-80v%12v%12v%12v%12v%12v%18v%18v%12v%12v%12v%12v\n", - benchName, total, send, recv, allocB, allocN, reqT, respT, ltc50, ltc90, l99, lAvg) +func printHeader() { + fmt.Printf("%-80s%12s%12s%12s%18s%18s%18s%18s%12s%12s%12s%12s\n", + "Name", "TotalOps", "SendOps", "RecvOps", "Bytes/op (B)", "Allocs/op (#)", + "RequestT", "ResponseT", "L-50", "L-90", "L-99", "L-Avg") +} + +func printline(benchName string, d stats.RunData) { + fmt.Printf("%-80s%12d%12d%12d%18.2f%18.2f%18.2f%18.2f%12v%12v%12v%12v\n", + benchName, d.TotalOps, d.SendOps, d.RecvOps, d.AllocedBytes, d.Allocs, + d.ReqT, d.RespT, d.Fiftieth, d.Ninetieth, d.NinetyNinth, d.Average) } func formatBenchmark(fileName string) { @@ -122,12 +129,9 @@ func formatBenchmark(fileName string) { wantFeatures[i] = !wantFeatures[i] } - printline("Name", "TotalOps", "SendOps", "RecvOps", "Alloc (B)", "Alloc (#)", - "RequestT", "ResponseT", "L-50", "L-90", "L-99", "L-Avg") + printHeader() for _, r := range results { - d := r.Data - printline(r.RunMode+r.Features.PrintableName(wantFeatures), d.TotalOps, d.SendOps, d.RecvOps, - d.AllocedBytes, d.Allocs, d.ReqT, d.RespT, d.Fiftieth, d.Ninetieth, d.NinetyNinth, d.Average) + printline(r.RunMode+r.Features.PrintableName(wantFeatures), r.Data) } } diff --git a/benchmark/stats/stats.go b/benchmark/stats/stats.go index 70972cb8..6829cd21 100644 --- a/benchmark/stats/stats.go +++ b/benchmark/stats/stats.go @@ -200,9 +200,9 @@ type RunData struct { // run. Only makes sense for unconstrained workloads. RecvOps uint64 // AllocedBytes is the average memory allocation in bytes per operation. - AllocedBytes uint64 + AllocedBytes float64 // Allocs is the average number of memory allocations per operation. - Allocs uint64 + Allocs float64 // ReqT is the average request throughput associated with this run. ReqT float64 // RespT is the average response throughput associated with this run. @@ -275,8 +275,8 @@ func (s *Stats) EndRun(count uint64) { r := &s.results[len(s.results)-1] r.Data = RunData{ TotalOps: count, - AllocedBytes: s.stopMS.TotalAlloc - s.startMS.TotalAlloc, - Allocs: s.stopMS.Mallocs - s.startMS.Mallocs, + AllocedBytes: float64(s.stopMS.TotalAlloc-s.startMS.TotalAlloc) / float64(count), + Allocs: float64(s.stopMS.Mallocs-s.startMS.Mallocs) / float64(count), ReqT: float64(count) * float64(r.Features.ReqSizeBytes) * 8 / r.Features.BenchTime.Seconds(), RespT: float64(count) * float64(r.Features.RespSizeBytes) * 8 / r.Features.BenchTime.Seconds(), } @@ -296,8 +296,8 @@ func (s *Stats) EndUnconstrainedRun(req uint64, resp uint64) { r.Data = RunData{ SendOps: req, RecvOps: resp, - AllocedBytes: (s.stopMS.TotalAlloc - s.startMS.TotalAlloc) / ((req + resp) / 2), - Allocs: (s.stopMS.Mallocs - s.startMS.Mallocs) / ((req + resp) / 2), + AllocedBytes: float64(s.stopMS.TotalAlloc-s.startMS.TotalAlloc) / float64((req+resp)/2), + Allocs: float64(s.stopMS.Mallocs-s.startMS.Mallocs) / float64((req+resp)/2), ReqT: float64(req) * float64(r.Features.ReqSizeBytes) * 8 / r.Features.BenchTime.Seconds(), RespT: float64(resp) * float64(r.Features.RespSizeBytes) * 8 / r.Features.BenchTime.Seconds(), }