Utils,
buildPerformanceStatisticsMessage,
logger,
+ median,
+ nthPercentile,
+ stdDeviation,
} from '../utils';
export class PerformanceStatistics {
timestamp: entry.startTime,
value: entry.duration,
}));
- this.statistics.statisticsData.get(entryName).medTimeMeasurement = Utils.median(
+ this.statistics.statisticsData.get(entryName).medTimeMeasurement = median(
this.extractTimeSeriesValues(
this.statistics.statisticsData.get(entryName).timeMeasurementSeries
)
);
this.statistics.statisticsData.get(entryName).ninetyFiveThPercentileTimeMeasurement =
- Utils.percentile(
+ nthPercentile(
this.extractTimeSeriesValues(
this.statistics.statisticsData.get(entryName).timeMeasurementSeries
),
95
);
- this.statistics.statisticsData.get(entryName).stdDevTimeMeasurement = Utils.stdDeviation(
+ this.statistics.statisticsData.get(entryName).stdDevTimeMeasurement = stdDeviation(
this.extractTimeSeriesValues(
this.statistics.statisticsData.get(entryName).timeMeasurementSeries
)
--- /dev/null
+import { Utils } from './Utils';
+
+export const median = (dataSet: number[]): number => {
+ if (Utils.isEmptyArray(dataSet)) {
+ return 0;
+ }
+ if (Array.isArray(dataSet) === true && dataSet.length === 1) {
+ return dataSet[0];
+ }
+ const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
+ return (
+ (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) / 2
+ );
+};
+
+// TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
+export const nthPercentile = (dataSet: number[], percentile: number): number => {
+ if (percentile < 0 && percentile > 100) {
+ throw new RangeError('Percentile is not between 0 and 100');
+ }
+ if (Utils.isEmptyArray(dataSet)) {
+ return 0;
+ }
+ const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
+ if (percentile === 0 || sortedDataSet.length === 1) {
+ return sortedDataSet[0];
+ }
+ if (percentile === 100) {
+ return sortedDataSet[sortedDataSet.length - 1];
+ }
+ const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1);
+ const percentileIndexInteger = Math.floor(percentileIndexBase);
+ if (!Utils.isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) {
+ return (
+ sortedDataSet[percentileIndexInteger] +
+ (percentileIndexBase - percentileIndexInteger) *
+ (sortedDataSet[percentileIndexInteger + 1] - sortedDataSet[percentileIndexInteger])
+ );
+ }
+ return sortedDataSet[percentileIndexInteger];
+};
+
+export const stdDeviation = (dataSet: number[]): number => {
+ let totalDataSet = 0;
+ for (const data of dataSet) {
+ totalDataSet += data;
+ }
+ const dataSetMean = totalDataSet / dataSet.length;
+ let totalGeometricDeviation = 0;
+ for (const data of dataSet) {
+ const deviation = data - dataSetMean;
+ totalGeometricDeviation += deviation * deviation;
+ }
+ return Math.sqrt(totalGeometricDeviation / dataSet.length);
+};
}
return '(Unknown)';
}
-
- public static median(dataSet: number[]): number {
- if (Utils.isEmptyArray(dataSet)) {
- return 0;
- }
- if (Array.isArray(dataSet) === true && dataSet.length === 1) {
- return dataSet[0];
- }
- const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
- return (
- (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) /
- 2
- );
- }
-
- // TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
- public static percentile(dataSet: number[], percentile: number): number {
- if (percentile < 0 && percentile > 100) {
- throw new RangeError('Percentile is not between 0 and 100');
- }
- if (Utils.isEmptyArray(dataSet)) {
- return 0;
- }
- const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
- if (percentile === 0 || sortedDataSet.length === 1) {
- return sortedDataSet[0];
- }
- if (percentile === 100) {
- return sortedDataSet[sortedDataSet.length - 1];
- }
- const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1);
- const percentileIndexInteger = Math.floor(percentileIndexBase);
- if (!Utils.isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) {
- return (
- sortedDataSet[percentileIndexInteger] +
- (percentileIndexBase - percentileIndexInteger) *
- (sortedDataSet[percentileIndexInteger + 1] - sortedDataSet[percentileIndexInteger])
- );
- }
- return sortedDataSet[percentileIndexInteger];
- }
-
- public static stdDeviation(dataSet: number[]): number {
- let totalDataSet = 0;
- for (const data of dataSet) {
- totalDataSet += data;
- }
- const dataSetMean = totalDataSet / dataSet.length;
- let totalGeometricDeviation = 0;
- for (const data of dataSet) {
- const deviation = data - dataSetMean;
- totalGeometricDeviation += deviation * deviation;
- }
- return Math.sqrt(totalGeometricDeviation / dataSet.length);
- }
}
buildStoppedMessage,
} from './MessageChannelUtils';
export { Utils } from './Utils';
+export { median, nthPercentile, stdDeviation } from './StatisticUtils';
export { logger } from './Logger';
import { CircularArray } from '../../src/utils/CircularArray';
-describe('Circular array test suite', () => {
+describe('CircularArray test suite', () => {
it('Verify that circular array can be instantiated', () => {
const circularArray = new CircularArray();
expect(circularArray).toBeInstanceOf(CircularArray);
--- /dev/null
+import { expect } from 'expect';
+
+import { median, nthPercentile, stdDeviation } from '../../src/utils/StatisticUtils';
+
+describe('StatisticUtils test suite', () => {
+ it('Verify median()', () => {
+ expect(median([])).toBe(0);
+ expect(median([0.08])).toBe(0.08);
+ expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05);
+ expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535);
+ });
+
+ it('Verify nthPercentile()', () => {
+ expect(nthPercentile([], 25)).toBe(0);
+ expect(nthPercentile([0.08], 50)).toBe(0.08);
+ const array0 = [0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03];
+ expect(nthPercentile(array0, 0)).toBe(0.25);
+ expect(nthPercentile(array0, 50)).toBe(3.05);
+ expect(nthPercentile(array0, 80)).toBe(4.974);
+ expect(nthPercentile(array0, 85)).toBe(5.131);
+ expect(nthPercentile(array0, 90)).toBe(5.434);
+ expect(nthPercentile(array0, 95)).toBe(5.736999999999999);
+ expect(nthPercentile(array0, 100)).toBe(6.04);
+ });
+
+ it('Verify stdDeviation()', () => {
+ expect(stdDeviation([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(2.0256064851429216);
+ });
+});
expect(Utils.isEmptyObject(new WeakMap())).toBe(false);
expect(Utils.isEmptyObject(new WeakSet())).toBe(false);
});
-
- it('Verify median()', () => {
- expect(Utils.median([])).toBe(0);
- expect(Utils.median([0.08])).toBe(0.08);
- expect(Utils.median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05);
- expect(Utils.median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535);
- });
-
- it('Verify percentile()', () => {
- expect(Utils.percentile([], 25)).toBe(0);
- expect(Utils.percentile([0.08], 50)).toBe(0.08);
- const array0 = [0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03];
- expect(Utils.percentile(array0, 0)).toBe(0.25);
- expect(Utils.percentile(array0, 50)).toBe(3.05);
- expect(Utils.percentile(array0, 80)).toBe(4.974);
- expect(Utils.percentile(array0, 85)).toBe(5.131);
- expect(Utils.percentile(array0, 90)).toBe(5.434);
- expect(Utils.percentile(array0, 95)).toBe(5.736999999999999);
- expect(Utils.percentile(array0, 100)).toBe(6.04);
- });
-
- it('Verify stdDeviation()', () => {
- expect(Utils.stdDeviation([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(2.0256064851429216);
- });
});