Skip to content

Commit

Permalink
feat: add types for analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego Ferreiro Val committed Jun 19, 2019
1 parent 91ecf4f commit baf1f42
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
48 changes: 19 additions & 29 deletions packages/@best/analyzer/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BenchmarkResultsSnapshot, BenchmarkResultNode, BenchmarkMetricNames, BenchmarkStats } from "@best/types";
import { VERSION } from './constants';
import { BenchmarkResultsSnapshot, BenchmarkResultNode, BenchmarkMetricNames, BenchmarkStats, AllBenchmarksMetricsMap, BenchmarkMetricsAggregate, AllBenchmarkMetricStatsMap, StatsNode, BenchmarkMetricStatsMap } from "@best/types";
import { quantile, mean, median, variance, medianAbsoluteDeviation, compare as compareSamples } from './stats';

function computeSampleStats(arr: number[], samplesQuantileThreshold: number): BenchmarkStats {
Expand All @@ -19,15 +19,8 @@ function computeSampleStats(arr: number[], samplesQuantileThreshold: number): Be
};
}

type BenchmarkMetricsAggregate = { [key in BenchmarkMetricNames]?: number[] }

// This type will hold as keys all benchmark names, and then an array with all results
interface BenchmarkMetricsMap {
[key: string]: BenchmarkMetricsAggregate
}

// Given an iteration benchmark (whith nested benchmarks), collect its metrics
function collectResults({ name, metrics, nodes, aggregate }: BenchmarkResultNode, collector: BenchmarkMetricsMap) {
function collectResults({ name, metrics, nodes, aggregate }: BenchmarkResultNode, collector: AllBenchmarksMetricsMap) {
let collectorNode = collector[name];
if (!collectorNode) {
collectorNode = collector[name] = { script: [], aggregate: [] };
Expand Down Expand Up @@ -56,21 +49,18 @@ function collectResults({ name, metrics, nodes, aggregate }: BenchmarkResultNode
return collector;
}

function createStructure({ nodes, name, type }: BenchmarkResultNode, collector: any): any {
function createStatsStructure({ nodes: children = [], name, type }: BenchmarkResultNode, collector: AllBenchmarkMetricStatsMap): StatsNode {
if (type === "benchmark") {
const newNode = collector[name];
newNode.name = name;
return newNode;
const stats = collector[name];
const metrics = Object.keys(stats).reduce((metricReducer: any, metric: string) => {
metricReducer[metric as BenchmarkMetricNames] = { stats: stats[metric as BenchmarkMetricNames] };
return metricReducer;
}, {});
return { type, name, metrics };
} else {
const nodes = children.map((childNode: BenchmarkResultNode) => createStatsStructure(childNode, collector))
return { type, name, nodes };
}

if (nodes) {
return {
name,
nodes: nodes.map((childNode: any) => createStructure(childNode, collector)),
};
}

return collector[name];
}

export async function analyzeBenchmarks(benchmarkResults: BenchmarkResultsSnapshot[]) {
Expand All @@ -81,31 +71,31 @@ export async function analyzeBenchmarks(benchmarkResults: BenchmarkResultsSnapsh
const structure = results[0];

// Collect the metrics for the nested benchmarks within
const collector: BenchmarkMetricsMap = results.reduce((reducer: BenchmarkMetricsMap, node: BenchmarkResultNode) => collectResults(node, reducer), {});
const collector: AllBenchmarksMetricsMap = results.reduce((reducer: AllBenchmarksMetricsMap, node: BenchmarkResultNode) => collectResults(node, reducer), {});

// For each metric
const benchmarkStats = Object.keys(collector).reduce((stats: any, benchmarkName: string) => {
const benchmarkStats: AllBenchmarkMetricStatsMap = Object.keys(collector).reduce((stats: AllBenchmarkMetricStatsMap, benchmarkName: string) => {
const benchmarkMetrics = collector[benchmarkName];

stats[benchmarkName] = Object.keys(benchmarkMetrics).reduce((metricStats: any, metric: string) => {
stats[benchmarkName] = Object.keys(benchmarkMetrics).reduce((metricStats: BenchmarkMetricStatsMap, metric: string) => {
const metricResults = benchmarkMetrics[metric as BenchmarkMetricNames];
if (Array.isArray(metricResults) && metricResults.length > 0) {
metricStats[metric] = computeSampleStats(metricResults, projectConfig.samplesQuantileThreshold);
metricStats[metric as BenchmarkMetricNames] = computeSampleStats(metricResults, projectConfig.samplesQuantileThreshold);
}
return metricStats;
}, {});

return stats;
}, {});

const benchmarkStructure = createStructure(structure, benchmarkStats);
const benchmarkStructure = createStatsStructure(structure, benchmarkStats);

console.log(benchmarkStructure);
console.log(JSON.stringify(benchmarkStructure, null, ' '));

benchmarkResult.stats = {
version: VERSION,
benchmarkName,
benchmarks: benchmarkStructure.benchmarks,
benchmarks: benchmarkStructure.nodes,
environment,
};
}),
Expand Down
9 changes: 0 additions & 9 deletions packages/@best/types/src/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,3 @@ export interface BenchmarkResultsState {
executedIterations: number,
results: BenchmarkResultNode[];
}
export interface BenchmarkStats {
samples: number[],
sampleSize: number,
samplesQuantileThreshold: number,
mean: number,
median: number,
variance: number,
medianAbsoluteDeviation: number,
}
1 change: 1 addition & 0 deletions packages/@best/types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./config";
export * from "./benchmark";
export * from "./stats";
34 changes: 34 additions & 0 deletions packages/@best/types/src/stats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BenchmarkMetricNames } from "./benchmark";

export type BenchmarkStatsNames = "samples" | "sampleSize" | "samplesQuantileThreshold" | "mean" | "median" | "variance" | "medianAbsoluteDeviation";
export interface BenchmarkStats {
samples: number[],
sampleSize: number,
samplesQuantileThreshold: number,
mean: number,
median: number,
variance: number,
medianAbsoluteDeviation: number,
}

export type BenchmarkMetricsAggregate = { [key in BenchmarkMetricNames]?: number[] }
export type BenchmarkMetricStatsMap = { [key in BenchmarkMetricNames]?: BenchmarkStats; }

// This type will hold as keys all benchmark names, and then an array with all results
export interface AllBenchmarksMetricsMap { [key: string]: BenchmarkMetricsAggregate }
export interface AllBenchmarkMetricStatsMap { [key: string]: BenchmarkMetricStatsMap; }

export type MetricsStatsMap = {
[key in BenchmarkMetricNames]?: {
stats: {
[key in BenchmarkStatsNames]?: BenchmarkStats
}
}
}

export interface StatsNode {
type: "group" | "benchmark";
name: string;
nodes?: StatsNode[];
metrics?: MetricsStatsMap
}

0 comments on commit baf1f42

Please sign in to comment.