2 #include <boost/accumulators/accumulators.hpp>
3 #include <boost/accumulators/statistics.hpp>
10 struct LogHistogramBin
18 double cumulLatAverage;
19 double cumulLatMedian;
23 std::vector<LogHistogramBin> createLogHistogram(const T& bins,
24 std::deque<double> percentiles={0.001, 0.01, 0.1, 0.2, 0.5, 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 94, 95, 96, 97, 97.5, 98, 98.5, 99, 99.5, 99.6, 99.9, 99.99, 99.999, 99.9999})
26 uint64_t totcumul=0, sum=0;
28 for(const auto& c: bins) {
32 namespace ba=boost::accumulators;
33 ba::accumulator_set<double, ba::features<ba::tag::mean, ba::tag::median, ba::tag::variance>, unsigned> acc;
35 ba::accumulator_set<double, ba::features<ba::tag::mean, ba::tag::median, ba::tag::variance>, unsigned int> cumulstats;
38 std::vector<LogHistogramBin> ret;
39 for(const auto& c: bins) {
40 if(percentiles.empty())
45 acc(c.first/1000.0, ba::weight=c.second);
46 for(unsigned int i=0; i < c.second; ++i)
47 cumulstats(c.first/1000.0, ba::weight=1); // "weighted" does not work for median
48 if(sum > percentiles.front() * totcumul / 100.0) {
49 ret.push_back({100.0-percentiles.front(), (double)c.first/1000.0, ba::mean(acc), ba::median(acc), sqrt(ba::variance(acc)), bincount, ba::mean(cumulstats), ba::median(cumulstats)});
51 percentiles.pop_front();
56 std::sort(ret.begin(), ret.end(), [](const LogHistogramBin& a, const LogHistogramBin& b) {
57 return a.percentile < b.percentile;
63 void writeLogHistogramFile(const T& bins, std::ostream& out, std::deque<double> percentiles={0.001, 0.01, 0.1, 0.2, 0.5, 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 94, 95, 96, 97, 97.5, 98, 98.5, 99, 99.5, 99.6, 99.9, 99.99, 99.999, 99.9999} )
66 auto vec = createLogHistogram(bins, percentiles);
67 out<< R"(# set logscale xy
72 # set xlabel "Slowest percentile"
73 # set ylabel "Millisecond response time"
75 # set output 'log-histogram.svg'
76 # plot 'log-histogram' using 1:2 with linespoints title 'Average latency per percentile', \
77 # 'log-histogram' using 1:6 with linespoints title 'Cumulative average latency', \
78 # 'log-histogram' using 1:7 with linespoints title 'Cumulative median latency')"<<"\n";
80 out<<"# slow-percentile usec-latency-mean usec-latency-max usec-latency-median usec-latency-stddev usec-latency-cumul usec-latency-median-cumul num-queries\n";
83 for(const auto& e : vec) {
84 out<<e.percentile<<" "<<e.latAverage<<" "<<e.latLimit<<" "<<e.latMedian<<" "<<e.latStddev<<" "<<e.cumulLatAverage<<" "<<e.cumulLatMedian<<" "<<e.count<<"\n";
90 void writeFullHistogramFile(const T& bins, double binMsec, std::ofstream& out)
92 std::map<unsigned int, uint64_t> reducedBins;
93 for(const auto& b : bins) {
94 reducedBins[b.first/(1000.0*binMsec)]+=b.second;
96 out<<"# msec-bin-low count\n";
97 for(const auto& rb : reducedBins) {
98 out<<rb.first*binMsec<<" "<<rb.second<<"\n";