| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- "use strict";
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- /*
- * This is a TypeScript port of the original Java version, which was written by
- * Gil Tene as described in
- * https://github.com/HdrHistogram/HdrHistogram
- * and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
- const fc = require("fast-check");
- const hdr = require("./index");
- const wasm_1 = require("./wasm");
- const runFromStryker = __dirname.includes("stryker");
- const runnerOptions = {
- numRuns: runFromStryker ? 10 : 1000,
- verbose: true,
- };
- describe("Histogram percentile computation", () => {
- beforeAll(wasm_1.initWebAssembly);
- const numberOfSignificantValueDigits = 3;
- [true, false].forEach((useWebAssembly) => [16, "packed"].forEach((bitBucketSize) => it(`Histogram ${bitBucketSize} (wasm: ${useWebAssembly}) should be accurate according to its significant figures`, () => __awaiter(void 0, void 0, void 0, function* () {
- yield wasm_1.initWebAssembly();
- fc.assert(fc.property(arbData(2000), (numbers) => {
- const histogram = hdr.build({
- bitBucketSize,
- numberOfSignificantValueDigits,
- useWebAssembly,
- });
- numbers.forEach((n) => histogram.recordValue(n));
- const actual = quantile(numbers, 90);
- const got = histogram.getValueAtPercentile(90);
- const relativeError = Math.abs(1 - got / actual);
- const variation = Math.pow(10, -numberOfSignificantValueDigits);
- histogram.destroy();
- return relativeError < variation;
- }), runnerOptions);
- }))));
- });
- describe("Histogram percentile computation (packed vs classic)", () => {
- const numberOfSignificantValueDigits = 3;
- const classicHistogram = hdr.build({
- numberOfSignificantValueDigits,
- });
- const histogram = hdr.build({
- numberOfSignificantValueDigits,
- bitBucketSize: "packed",
- useWebAssembly: false,
- });
- it(`should be accurate according to its significant figures`, () => {
- fc.assert(fc.property(arbData(5), (numbers) => {
- histogram.reset();
- classicHistogram.reset();
- numbers.forEach((n) => histogram.recordValue(n));
- numbers.forEach((n) => classicHistogram.recordValue(n));
- const actual = classicHistogram.getValueAtPercentile(90);
- const got = histogram.getValueAtPercentile(90);
- return actual === got;
- }), runnerOptions);
- });
- });
- describe("Histogram percentile computation with CO correction (wasm vs js)", () => {
- beforeAll(wasm_1.initWebAssembly);
- let jsHistogram;
- let wasmHistogram;
- beforeEach(() => {
- jsHistogram = hdr.build({
- useWebAssembly: false,
- });
- wasmHistogram = hdr.build({
- useWebAssembly: true,
- });
- });
- afterEach(() => {
- jsHistogram.destroy();
- wasmHistogram.destroy();
- });
- it(`should be accurate according to its significant figures`, () => {
- fc.assert(fc.property(arbData(1, 100 * 1000), (numbers) => {
- jsHistogram.reset();
- wasmHistogram.reset();
- numbers.forEach((n) => {
- jsHistogram.recordValueWithExpectedInterval(n, 1000);
- });
- numbers.forEach((n) => {
- wasmHistogram.recordValueWithExpectedInterval(n, 1000);
- });
- const js = jsHistogram.getValueAtPercentile(90);
- const wasm = wasmHistogram.getValueAtPercentile(90);
- const relativeError = Math.abs(1 - js / wasm);
- const variation = Math.pow(10, -3);
- if (relativeError >= variation) {
- console.log({ js, wasm });
- }
- return relativeError < variation;
- }), runnerOptions);
- });
- });
- describe("Histogram encoding/decoding", () => {
- beforeAll(wasm_1.initWebAssembly);
- const numberOfSignificantValueDigits = 3;
- [true, false].forEach((useWebAssembly) => [8, 16, 32, 64, "packed"].forEach((bitBucketSize) => {
- it(`Histogram ${bitBucketSize} (wasm: ${useWebAssembly}) should keep all data after an encoding/decoding roundtrip`, () => {
- fc.assert(fc.property(arbData(1), fc.double(50, 100), (numbers, percentile) => {
- const histogram = hdr.build({
- bitBucketSize,
- numberOfSignificantValueDigits,
- useWebAssembly,
- });
- numbers.forEach((n) => histogram.recordValue(n));
- const encodedHistogram = hdr.encodeIntoCompressedBase64(histogram);
- const decodedHistogram = hdr.decodeFromCompressedBase64(encodedHistogram);
- const actual = histogram.getValueAtPercentile(percentile);
- const got = decodedHistogram.getValueAtPercentile(percentile);
- histogram.destroy();
- decodedHistogram.destroy();
- return actual === got;
- }), runnerOptions);
- });
- }));
- });
- const arbData = (size, max = Number.MAX_SAFE_INTEGER) => fc.array(fc.integer(1, max), size, size);
- // reference implementation
- const quantile = (inputData, percentile) => {
- const data = [...inputData].sort((a, b) => a - b);
- const index = (percentile / 100) * (data.length - 1);
- let result;
- if (Math.floor(index) === index) {
- result = data[index];
- }
- else {
- const i = Math.floor(index);
- const fraction = index - i;
- result = data[i] + (data[i + 1] - data[i]) * fraction;
- }
- return result;
- };
- //# sourceMappingURL=Histogram.fc.spec.js.map
|