forked from tylertreat/bench
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsummary.go
124 lines (111 loc) · 4.55 KB
/
summary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package bench
import (
"fmt"
"os"
"time"
"github.com/codahale/hdrhistogram"
)
// Summary contains the results of a Benchmark run.
type Summary struct {
Connections uint64
RequestRate uint64
SuccessTotal uint64
ErrorTotal uint64
TimeElapsed time.Duration
SuccessHistogram *hdrhistogram.Histogram
UncorrectedSuccessHistogram *hdrhistogram.Histogram
ErrorHistogram *hdrhistogram.Histogram
UncorrectedErrorHistogram *hdrhistogram.Histogram
Throughput float64
}
// String returns a stringified version of the Summary.
func (s *Summary) String() string {
return fmt.Sprintf(
"\n{Connections: %d, RequestRate: %d, RequestTotal: %d, SuccessTotal: %d, ErrorTotal: %d, TimeElapsed: %s, Throughput: %.2f/s}",
s.Connections, s.RequestRate, (s.SuccessTotal + s.ErrorTotal), s.SuccessTotal, s.ErrorTotal, s.TimeElapsed, s.Throughput)
}
// GenerateLatencyDistribution generates a text file containing the specified
// latency distribution in a format plottable by
// http://hdrhistogram.github.io/HdrHistogram/plotFiles.html. Percentiles is a
// list of percentiles to include, e.g. 10.0, 50.0, 99.0, 99.99, etc. If
// percentiles is nil, it defaults to a logarithmic percentile scale. If a
// request rate was specified for the benchmark, this will also generate an
// uncorrected distribution file which does not account for coordinated
// omission.
func (s *Summary) GenerateLatencyDistribution(percentiles Percentiles, file string) error {
return generateLatencyDistribution(s.SuccessHistogram, s.UncorrectedSuccessHistogram, s.RequestRate, percentiles, file)
}
// GenerateErrorLatencyDistribution generates a text file containing the specified
// latency distribution (of requests that resulted in errors) in a format plottable by
// http://hdrhistogram.github.io/HdrHistogram/plotFiles.html. Percentiles is a
// list of percentiles to include, e.g. 10.0, 50.0, 99.0, 99.99, etc. If
// percentiles is nil, it defaults to a logarithmic percentile scale. If a
// request rate was specified for the benchmark, this will also generate an
// uncorrected distribution file which does not account for coordinated
// omission.
func (s *Summary) GenerateErrorLatencyDistribution(percentiles Percentiles, file string) error {
return generateLatencyDistribution(s.ErrorHistogram, s.UncorrectedErrorHistogram, s.RequestRate, percentiles, file)
}
func getOneByPercentile(percentile float64) float64 {
if percentile < 100 {
return 1 / (1 - (percentile / 100))
}
return float64(10000000)
}
func generateLatencyDistribution(histogram, unHistogram *hdrhistogram.Histogram, requestRate uint64, percentiles Percentiles, file string) error {
if percentiles == nil {
percentiles = Logarithmic
}
f, err := os.Create(file)
if err != nil {
return err
}
defer f.Close()
f.WriteString("Value Percentile TotalCount 1/(1-Percentile)\n\n")
totalCount := histogram.TotalCount()
for _, percentile := range percentiles {
value := float64(histogram.ValueAtQuantile(percentile)) / 1000000
oneByPercentile := getOneByPercentile(percentile)
countAtPercentile := int64(((percentile / 100) * float64(totalCount)) + 0.5)
_, err := f.WriteString(fmt.Sprintf("%f %f %d %f\n",
value, percentile/100, countAtPercentile, oneByPercentile))
if err != nil {
return err
}
}
// Generate uncorrected distribution.
if requestRate > 0 {
f, err := os.Create("uncorrected_" + file)
if err != nil {
return err
}
defer f.Close()
f.WriteString("Value Percentile TotalCount 1/(1-Percentile)\n\n")
totalCount = unHistogram.TotalCount()
for _, percentile := range percentiles {
value := float64(unHistogram.ValueAtQuantile(percentile)) / 1000000
oneByPercentile := getOneByPercentile(percentile)
countAtPercentile := int64(((percentile / 100) * float64(totalCount)) + 0.5)
_, err := f.WriteString(fmt.Sprintf("%f %f %d %f\n",
value, percentile/100, countAtPercentile, oneByPercentile))
if err != nil {
return err
}
}
}
return nil
}
// merge the other Summary into this one.
func (s *Summary) merge(o *Summary) {
if o.TimeElapsed > s.TimeElapsed {
s.TimeElapsed = o.TimeElapsed
}
s.SuccessHistogram.Merge(o.SuccessHistogram)
s.UncorrectedSuccessHistogram.Merge(o.UncorrectedSuccessHistogram)
s.ErrorHistogram.Merge(o.ErrorHistogram)
s.UncorrectedErrorHistogram.Merge(o.UncorrectedErrorHistogram)
s.SuccessTotal += o.SuccessTotal
s.ErrorTotal += o.ErrorTotal
s.Throughput += o.Throughput
s.RequestRate += o.RequestRate
}