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
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "latency_analyzer.h"
#include <cmath>
namespace vbench {
double
LatencyAnalyzer::getN(size_t n) const
{
size_t acc = 0;
for (size_t i = 0; i < _hist.size(); ++i) {
acc += _hist[i];
if (acc > n) {
return (((double)i) / 1000.0);
}
}
return _max;
}
double
LatencyAnalyzer::getPercentile(double per) const
{
double target = std::max((((double)(_cnt - 1)) * (per / 100.0)), 0.0);
size_t before = (size_t)std::floor(target);
size_t after = (size_t)std::ceil(target);
double factor = std::ceil(target) - target;
return (factor * getN(before) + (1.0 - factor) * getN(after));
}
string
LatencyAnalyzer::Stats::toString() const
{
string str = "Latency {\n";
str += strfmt(" min: %g\n", min);
str += strfmt(" avg: %g\n", avg);
str += strfmt(" max: %g\n", max);
str += strfmt(" 50%%: %g\n", per50);
str += strfmt(" 95%%: %g\n", per95);
str += strfmt(" 99%%: %g\n", per99);
str += "}\n";
return str;
}
LatencyAnalyzer::LatencyAnalyzer(Handler<Request> &next)
: _next(next),
_cnt(0),
_min(0.0),
_max(0.0),
_total(0.0),
_hist(10000, 0)
{
}
LatencyAnalyzer::~LatencyAnalyzer() = default;
void
LatencyAnalyzer::handle(Request::UP request)
{
if (request->status() == Request::STATUS_OK) {
addLatency(request->latency());
}
_next.handle(std::move(request));
}
void
LatencyAnalyzer::report()
{
fprintf(stdout, "%s\n", getStats().toString().c_str());
}
void
LatencyAnalyzer::addLatency(double latency)
{
if (_cnt == 0 || latency < _min) {
_min = latency;
}
if (_cnt == 0 || latency > _max) {
_max = latency;
}
++_cnt;
_total += latency;
size_t idx = (size_t)(latency * 1000.0 + 0.5);
if (idx < _hist.size()) {
++_hist[idx];
}
}
LatencyAnalyzer::Stats
LatencyAnalyzer::getStats() const
{
Stats stats;
stats.min = _min;
if (_cnt > 0) {
stats.avg = (_total / (double)_cnt);
}
stats.max = _max;
stats.per50 = getPercentile(50.0);
stats.per95 = getPercentile(95.0);
stats.per99 = getPercentile(99.0);
return stats;
}
} // namespace vbench
|