github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/benchmark/benchresult/main.go (about) 1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 /* 20 To format the benchmark result: 21 go run benchmark/benchresult/main.go resultfile 22 23 To see the performance change based on a old result: 24 go run benchmark/benchresult/main.go resultfile_old resultfile 25 It will print the comparison result of intersection benchmarks between two files. 26 27 */ 28 package main 29 30 import ( 31 "encoding/gob" 32 "fmt" 33 "log" 34 "os" 35 "strings" 36 "time" 37 38 "github.com/hxx258456/ccgo/grpc/benchmark/stats" 39 ) 40 41 func createMap(fileName string) map[string]stats.BenchResults { 42 f, err := os.Open(fileName) 43 if err != nil { 44 log.Fatalf("Read file %s error: %s\n", fileName, err) 45 } 46 defer f.Close() 47 var data []stats.BenchResults 48 decoder := gob.NewDecoder(f) 49 if err = decoder.Decode(&data); err != nil { 50 log.Fatalf("Decode file %s error: %s\n", fileName, err) 51 } 52 m := make(map[string]stats.BenchResults) 53 for _, d := range data { 54 m[d.RunMode+"-"+d.Features.String()] = d 55 } 56 return m 57 } 58 59 func intChange(title string, val1, val2 uint64) string { 60 return fmt.Sprintf("%20s %12d %12d %8.2f%%\n", title, val1, val2, float64(int64(val2)-int64(val1))*100/float64(val1)) 61 } 62 63 func floatChange(title string, val1, val2 float64) string { 64 return fmt.Sprintf("%20s %12.2f %12.2f %8.2f%%\n", title, val1, val2, float64(int64(val2)-int64(val1))*100/float64(val1)) 65 } 66 func timeChange(title string, val1, val2 time.Duration) string { 67 return fmt.Sprintf("%20s %12s %12s %8.2f%%\n", title, val1.String(), 68 val2.String(), float64(val2-val1)*100/float64(val1)) 69 } 70 71 func strDiff(title, val1, val2 string) string { 72 return fmt.Sprintf("%20s %12s %12s\n", title, val1, val2) 73 } 74 75 func compareTwoMap(m1, m2 map[string]stats.BenchResults) { 76 for k2, v2 := range m2 { 77 if v1, ok := m1[k2]; ok { 78 changes := k2 + "\n" 79 changes += fmt.Sprintf("%20s %12s %12s %8s\n", "Title", "Before", "After", "Percentage") 80 changes += intChange("TotalOps", v1.Data.TotalOps, v2.Data.TotalOps) 81 changes += intChange("SendOps", v1.Data.SendOps, v2.Data.SendOps) 82 changes += intChange("RecvOps", v1.Data.RecvOps, v2.Data.RecvOps) 83 changes += floatChange("Bytes/op", v1.Data.AllocedBytes, v2.Data.AllocedBytes) 84 changes += floatChange("Allocs/op", v1.Data.Allocs, v2.Data.Allocs) 85 changes += floatChange("ReqT/op", v1.Data.ReqT, v2.Data.ReqT) 86 changes += floatChange("RespT/op", v1.Data.RespT, v2.Data.RespT) 87 changes += timeChange("50th-Lat", v1.Data.Fiftieth, v2.Data.Fiftieth) 88 changes += timeChange("90th-Lat", v1.Data.Ninetieth, v2.Data.Ninetieth) 89 changes += timeChange("99th-Lat", v1.Data.NinetyNinth, v2.Data.NinetyNinth) 90 changes += timeChange("Avg-Lat", v1.Data.Average, v2.Data.Average) 91 changes += strDiff("GoVersion", v1.GoVersion, v2.GoVersion) 92 changes += strDiff("GrpcVersion", v1.GrpcVersion, v2.GrpcVersion) 93 fmt.Printf("%s\n", changes) 94 } 95 } 96 } 97 98 func compareBenchmark(file1, file2 string) { 99 compareTwoMap(createMap(file1), createMap(file2)) 100 } 101 102 func printHeader() { 103 fmt.Printf("%-80s%12s%12s%12s%18s%18s%18s%18s%12s%12s%12s%12s\n", 104 "Name", "TotalOps", "SendOps", "RecvOps", "Bytes/op (B)", "Allocs/op (#)", 105 "RequestT", "ResponseT", "L-50", "L-90", "L-99", "L-Avg") 106 } 107 108 func printline(benchName string, d stats.RunData) { 109 fmt.Printf("%-80s%12d%12d%12d%18.2f%18.2f%18.2f%18.2f%12v%12v%12v%12v\n", 110 benchName, d.TotalOps, d.SendOps, d.RecvOps, d.AllocedBytes, d.Allocs, 111 d.ReqT, d.RespT, d.Fiftieth, d.Ninetieth, d.NinetyNinth, d.Average) 112 } 113 114 func formatBenchmark(fileName string) { 115 f, err := os.Open(fileName) 116 if err != nil { 117 log.Fatalf("Read file %s error: %s\n", fileName, err) 118 } 119 defer f.Close() 120 var results []stats.BenchResults 121 decoder := gob.NewDecoder(f) 122 if err = decoder.Decode(&results); err != nil { 123 log.Fatalf("Decode file %s error: %s\n", fileName, err) 124 } 125 if len(results) == 0 { 126 log.Fatalf("No benchmark results in file %s\n", fileName) 127 } 128 129 fmt.Println("\nShared features:\n" + strings.Repeat("-", 20)) 130 fmt.Print(results[0].Features.SharedFeatures(results[0].SharedFeatures)) 131 fmt.Println(strings.Repeat("-", 35)) 132 133 wantFeatures := results[0].SharedFeatures 134 for i := 0; i < len(results[0].SharedFeatures); i++ { 135 wantFeatures[i] = !wantFeatures[i] 136 } 137 138 printHeader() 139 for _, r := range results { 140 printline(r.RunMode+r.Features.PrintableName(wantFeatures), r.Data) 141 } 142 } 143 144 func main() { 145 if len(os.Args) == 2 { 146 formatBenchmark(os.Args[1]) 147 } else { 148 compareBenchmark(os.Args[1], os.Args[2]) 149 } 150 }