123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- /*
- To format the benchmark result:
- go run benchmark/benchresult/main.go resultfile
- To see the performance change based on a old result:
- go run benchmark/benchresult/main.go resultfile_old resultfile
- It will print the comparison result of intersection benchmarks between two files.
- */
- package main
- import (
- "encoding/gob"
- "fmt"
- "log"
- "os"
- "strings"
- "time"
- "google.golang.org/grpc/benchmark/stats"
- )
- func createMap(fileName string) map[string]stats.BenchResults {
- f, err := os.Open(fileName)
- if err != nil {
- log.Fatalf("Read file %s error: %s\n", fileName, err)
- }
- defer f.Close()
- var data []stats.BenchResults
- decoder := gob.NewDecoder(f)
- if err = decoder.Decode(&data); err != nil {
- log.Fatalf("Decode file %s error: %s\n", fileName, err)
- }
- m := make(map[string]stats.BenchResults)
- for _, d := range data {
- m[d.RunMode+"-"+d.Features.String()] = d
- }
- return m
- }
- func intChange(title string, val1, val2 uint64) string {
- return fmt.Sprintf("%20s %12d %12d %8.2f%%\n", title, val1, val2, float64(int64(val2)-int64(val1))*100/float64(val1))
- }
- func floatChange(title string, val1, val2 float64) string {
- return fmt.Sprintf("%20s %12.2f %12.2f %8.2f%%\n", title, val1, val2, float64(int64(val2)-int64(val1))*100/float64(val1))
- }
- func timeChange(title string, val1, val2 time.Duration) string {
- return fmt.Sprintf("%20s %12s %12s %8.2f%%\n", title, val1.String(),
- val2.String(), float64(val2-val1)*100/float64(val1))
- }
- func strDiff(title, val1, val2 string) string {
- return fmt.Sprintf("%20s %12s %12s\n", title, val1, val2)
- }
- func compareTwoMap(m1, m2 map[string]stats.BenchResults) {
- for k2, v2 := range m2 {
- if v1, ok := m1[k2]; ok {
- changes := k2 + "\n"
- changes += fmt.Sprintf("%20s %12s %12s %8s\n", "Title", "Before", "After", "Percentage")
- 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 += 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)
- changes += timeChange("90th-Lat", v1.Data.Ninetieth, v2.Data.Ninetieth)
- changes += timeChange("99th-Lat", v1.Data.NinetyNinth, v2.Data.NinetyNinth)
- changes += timeChange("Avg-Lat", v1.Data.Average, v2.Data.Average)
- changes += strDiff("GoVersion", v1.GoVersion, v2.GoVersion)
- changes += strDiff("GrpcVersion", v1.GrpcVersion, v2.GrpcVersion)
- fmt.Printf("%s\n", changes)
- }
- }
- }
- func compareBenchmark(file1, file2 string) {
- compareTwoMap(createMap(file1), createMap(file2))
- }
- 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) {
- f, err := os.Open(fileName)
- if err != nil {
- log.Fatalf("Read file %s error: %s\n", fileName, err)
- }
- defer f.Close()
- var results []stats.BenchResults
- decoder := gob.NewDecoder(f)
- if err = decoder.Decode(&results); err != nil {
- log.Fatalf("Decode file %s error: %s\n", fileName, err)
- }
- if len(results) == 0 {
- log.Fatalf("No benchmark results in file %s\n", fileName)
- }
- fmt.Println("\nShared features:\n" + strings.Repeat("-", 20))
- fmt.Print(results[0].Features.SharedFeatures(results[0].SharedFeatures))
- fmt.Println(strings.Repeat("-", 35))
- wantFeatures := results[0].SharedFeatures
- for i := 0; i < len(results[0].SharedFeatures); i++ {
- wantFeatures[i] = !wantFeatures[i]
- }
- printHeader()
- for _, r := range results {
- printline(r.RunMode+r.Features.PrintableName(wantFeatures), r.Data)
- }
- }
- func main() {
- if len(os.Args) == 2 {
- formatBenchmark(os.Args[1])
- } else {
- compareBenchmark(os.Args[1], os.Args[2])
- }
- }
|