main.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. To format the benchmark result:
  20. go run benchmark/benchresult/main.go resultfile
  21. To see the performance change based on a old result:
  22. go run benchmark/benchresult/main.go resultfile_old resultfile
  23. It will print the comparison result of intersection benchmarks between two files.
  24. */
  25. package main
  26. import (
  27. "encoding/gob"
  28. "fmt"
  29. "log"
  30. "os"
  31. "strconv"
  32. "strings"
  33. "time"
  34. "google.golang.org/grpc/benchmark/stats"
  35. )
  36. func createMap(fileName string, m map[string]stats.BenchResults) {
  37. f, err := os.Open(fileName)
  38. if err != nil {
  39. log.Fatalf("Read file %s error: %s\n", fileName, err)
  40. }
  41. defer f.Close()
  42. var data []stats.BenchResults
  43. decoder := gob.NewDecoder(f)
  44. if err = decoder.Decode(&data); err != nil {
  45. log.Fatalf("Decode file %s error: %s\n", fileName, err)
  46. }
  47. for _, d := range data {
  48. m[d.RunMode+"-"+d.Features.String()] = d
  49. }
  50. }
  51. func intChange(title string, val1, val2 int64) string {
  52. return fmt.Sprintf("%10s %12s %12s %8.2f%%\n", title, strconv.FormatInt(val1, 10),
  53. strconv.FormatInt(val2, 10), float64(val2-val1)*100/float64(val1))
  54. }
  55. func timeChange(title int, val1, val2 time.Duration) string {
  56. return fmt.Sprintf("%10s %12s %12s %8.2f%%\n", strconv.Itoa(title)+" latency", val1.String(),
  57. val2.String(), float64(val2-val1)*100/float64(val1))
  58. }
  59. func compareTwoMap(m1, m2 map[string]stats.BenchResults) {
  60. for k2, v2 := range m2 {
  61. if v1, ok := m1[k2]; ok {
  62. changes := k2 + "\n"
  63. changes += fmt.Sprintf("%10s %12s %12s %8s\n", "Title", "Before", "After", "Percentage")
  64. changes += intChange("Bytes/op", v1.AllocedBytesPerOp, v2.AllocedBytesPerOp)
  65. changes += intChange("Allocs/op", v1.AllocsPerOp, v2.AllocsPerOp)
  66. changes += timeChange(v1.Latency[1].Percent, v1.Latency[1].Value, v2.Latency[1].Value)
  67. changes += timeChange(v1.Latency[2].Percent, v1.Latency[2].Value, v2.Latency[2].Value)
  68. fmt.Printf("%s\n", changes)
  69. }
  70. }
  71. }
  72. func compareBenchmark(file1, file2 string) {
  73. var BenchValueFile1 map[string]stats.BenchResults
  74. var BenchValueFile2 map[string]stats.BenchResults
  75. BenchValueFile1 = make(map[string]stats.BenchResults)
  76. BenchValueFile2 = make(map[string]stats.BenchResults)
  77. createMap(file1, BenchValueFile1)
  78. createMap(file2, BenchValueFile2)
  79. compareTwoMap(BenchValueFile1, BenchValueFile2)
  80. }
  81. func printline(benchName, ltc50, ltc90, allocByte, allocsOp interface{}) {
  82. fmt.Printf("%-80v%12v%12v%12v%12v\n", benchName, ltc50, ltc90, allocByte, allocsOp)
  83. }
  84. func formatBenchmark(fileName string) {
  85. f, err := os.Open(fileName)
  86. if err != nil {
  87. log.Fatalf("Read file %s error: %s\n", fileName, err)
  88. }
  89. defer f.Close()
  90. var data []stats.BenchResults
  91. decoder := gob.NewDecoder(f)
  92. if err = decoder.Decode(&data); err != nil {
  93. log.Fatalf("Decode file %s error: %s\n", fileName, err)
  94. }
  95. if len(data) == 0 {
  96. log.Fatalf("No data in file %s\n", fileName)
  97. }
  98. printPos := data[0].SharedPosion
  99. fmt.Println("\nShared features:\n" + strings.Repeat("-", 20))
  100. fmt.Print(stats.PartialPrintString(printPos, data[0].Features, true))
  101. fmt.Println(strings.Repeat("-", 35))
  102. for i := 0; i < len(data[0].SharedPosion); i++ {
  103. printPos[i] = !printPos[i]
  104. }
  105. printline("Name", "latency-50", "latency-90", "Alloc (B)", "Alloc (#)")
  106. for _, d := range data {
  107. name := d.RunMode + stats.PartialPrintString(printPos, d.Features, false)
  108. printline(name, d.Latency[1].Value.String(), d.Latency[2].Value.String(),
  109. d.AllocedBytesPerOp, d.AllocsPerOp)
  110. }
  111. }
  112. func main() {
  113. if len(os.Args) == 2 {
  114. formatBenchmark(os.Args[1])
  115. } else {
  116. compareBenchmark(os.Args[1], os.Args[2])
  117. }
  118. }