63 lines
2.1 KiB
C++
63 lines
2.1 KiB
C++
#include "fdbrpc/DDSketch.h"
|
|
#include "flow/Error.h"
|
|
#include "flow/IRandom.h"
|
|
#include "flow/UnitTest.h"
|
|
#include <limits>
|
|
#include <random>
|
|
#include "flow/actorcompiler.h" // has to be last include
|
|
void forceLinkDDSketchTests() {}
|
|
|
|
TEST_CASE("/fdbrpc/ddsketch/accuracy") {
|
|
|
|
int TRY = 100, SIZE = 1e6;
|
|
const int totalPercentiles = 7;
|
|
double targetPercentiles[totalPercentiles] = { .0001, .01, .1, .50, .90, .99, .9999 };
|
|
double stat[totalPercentiles] = { 0 };
|
|
for (int t = 0; t < TRY; t++) {
|
|
DDSketch<double> dd;
|
|
std::vector<double> nums;
|
|
for (int i = 0; i < SIZE; i++) {
|
|
static double a = 1, b = 1; // a skewed distribution
|
|
auto y = deterministicRandom()->random01();
|
|
auto num = b / pow(1 - y, 1 / a);
|
|
nums.push_back(num);
|
|
dd.addSample(num);
|
|
}
|
|
std::sort(nums.begin(), nums.end());
|
|
for (int percentID = 0; percentID < totalPercentiles; percentID++) {
|
|
double percentile = targetPercentiles[percentID];
|
|
double ground = nums[percentile * (SIZE - 1)], ddvalue = dd.percentile(percentile);
|
|
double relativeError = fabs(ground - ddvalue) / ground;
|
|
stat[percentID] += relativeError;
|
|
}
|
|
}
|
|
|
|
for (int percentID = 0; percentID < totalPercentiles; percentID++) {
|
|
printf("%.4lf per, relative error %.4lf\n", targetPercentiles[percentID], stat[percentID] / TRY);
|
|
}
|
|
|
|
return Void();
|
|
}
|
|
|
|
TEST_CASE("/fdbrpc/ddsketch/correctness") {
|
|
DDSketch<double> dd;
|
|
|
|
for (int i = 0; i < 4000; i++) {
|
|
// This generates a uniform real disitribution between the range of
|
|
// [0.0004, 0.01]
|
|
double sample = (static_cast<double>(deterministicRandom()->randomSkewedUInt32(40, 1000)) / 100000);
|
|
dd.addSample(sample);
|
|
}
|
|
double p50 = dd.percentile(0.5);
|
|
ASSERT(p50 > 0 && p50 != std::numeric_limits<double>::infinity());
|
|
double p90 = dd.percentile(0.9);
|
|
ASSERT(p90 > 0 && p90 != std::numeric_limits<double>::infinity());
|
|
double p95 = dd.percentile(0.95);
|
|
ASSERT(p95 > 0 && p95 != std::numeric_limits<double>::infinity());
|
|
double p99 = dd.percentile(0.99);
|
|
ASSERT(p99 > 0 && p99 != std::numeric_limits<double>::infinity());
|
|
double p999 = dd.percentile(0.999);
|
|
ASSERT(p999 > 0 && p999 != std::numeric_limits<double>::infinity());
|
|
return Void{};
|
|
}
|