flexi-bench 0.0.0-alpha.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/README.md +276 -3
- package/dist/api-types.d.ts +45 -0
- package/dist/api-types.js +35 -0
- package/dist/benchmark-runner.js +5 -5
- package/dist/benchmark.d.ts +2 -1
- package/dist/benchmark.js +160 -141
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/performance-observer.js +7 -20
- package/dist/reporters/benchmark-console-reporter.d.ts +4 -1
- package/dist/reporters/benchmark-console-reporter.js +20 -7
- package/dist/reporters/composite-reporter.d.ts +21 -0
- package/dist/reporters/composite-reporter.js +29 -0
- package/dist/reporters/json-suite-reporter.d.ts +26 -0
- package/dist/reporters/json-suite-reporter.js +38 -0
- package/dist/reporters/markdown-benchmark-reporter.d.ts +13 -1
- package/dist/reporters/markdown-benchmark-reporter.js +154 -18
- package/dist/reporters/markdown-suite-reporter.d.ts +16 -0
- package/dist/reporters/markdown-suite-reporter.js +140 -0
- package/dist/reporters/noop-reporter.js +1 -3
- package/dist/reporters/suite-console-reporter.d.ts +4 -0
- package/dist/reporters/suite-console-reporter.js +24 -8
- package/dist/results.d.ts +41 -2
- package/dist/results.js +63 -6
- package/dist/shared-api.d.ts +3 -1
- package/dist/shared-api.js +10 -6
- package/dist/suite.d.ts +11 -1
- package/dist/suite.js +44 -24
- package/dist/variation.d.ts +62 -0
- package/dist/variation.js +80 -3
- package/package.json +7 -2
package/dist/suite.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.Suite = void 0;
|
|
4
|
+
const api_types_1 = require("./api-types");
|
|
13
5
|
const suite_console_reporter_1 = require("./reporters/suite-console-reporter");
|
|
14
6
|
class Suite {
|
|
7
|
+
name;
|
|
8
|
+
benchmarks = [];
|
|
9
|
+
variations = [];
|
|
10
|
+
reporter;
|
|
11
|
+
benchmarkReporter;
|
|
12
|
+
errorStrategy = api_types_1.ErrorStrategy.Continue;
|
|
13
|
+
shouldSetErrorStrategyOnBenchmarks = false;
|
|
15
14
|
constructor(name, options) {
|
|
16
15
|
this.name = name;
|
|
17
|
-
this.benchmarks = [];
|
|
18
|
-
this.variations = [];
|
|
19
16
|
this.name = name;
|
|
20
17
|
this.benchmarks = [];
|
|
21
|
-
this.reporter =
|
|
18
|
+
this.reporter = options?.reporter || new suite_console_reporter_1.SuiteConsoleReporter();
|
|
22
19
|
}
|
|
23
20
|
addBenchmark(benchmark) {
|
|
24
21
|
this.benchmarks.push(benchmark);
|
|
@@ -40,19 +37,42 @@ class Suite {
|
|
|
40
37
|
this.benchmarkReporter = reporter;
|
|
41
38
|
return this;
|
|
42
39
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Sets the error strategy for the suite and optionally for the benchmarks.
|
|
42
|
+
* @param errorStrategy Determines what to do when an error occurs during a benchmark run. See {@link ErrorStrategy}
|
|
43
|
+
* @param opts Options for the error strategy. If `shouldSetOnBenchmarks` is true, the error strategy will be set on all benchmarks in the suite.
|
|
44
|
+
*/
|
|
45
|
+
withErrorStrategy(errorStrategy, opts) {
|
|
46
|
+
this.errorStrategy = errorStrategy;
|
|
47
|
+
if (opts?.shouldSetOnBenchmarks) {
|
|
48
|
+
this.shouldSetErrorStrategyOnBenchmarks = opts?.shouldSetOnBenchmarks;
|
|
49
|
+
}
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
async run() {
|
|
53
|
+
this.reporter.onSuiteStart?.(this.name);
|
|
54
|
+
const results = {};
|
|
55
|
+
for (const benchmark of this.benchmarks) {
|
|
56
|
+
this.reporter.onBenchmarkStart?.(benchmark.name);
|
|
57
|
+
benchmark.withVariations(this.variations);
|
|
58
|
+
if (this.benchmarkReporter) {
|
|
59
|
+
benchmark.withReporter(this.benchmarkReporter);
|
|
60
|
+
}
|
|
61
|
+
if (this.shouldSetErrorStrategyOnBenchmarks) {
|
|
62
|
+
benchmark.withErrorStrategy(this.errorStrategy);
|
|
63
|
+
}
|
|
64
|
+
const benchmarkResults = await benchmark.run();
|
|
65
|
+
results[benchmark.name] = benchmarkResults;
|
|
66
|
+
this.reporter.onBenchmarkEnd?.(benchmark.name, benchmarkResults);
|
|
67
|
+
}
|
|
68
|
+
this.reporter.report(results);
|
|
69
|
+
if (this.errorStrategy === api_types_1.ErrorStrategy.DelayedThrow) {
|
|
70
|
+
const failedResults = Object.values(results).flatMap((r) => r.filter((r) => r.failed));
|
|
71
|
+
if (failedResults.length > 0) {
|
|
72
|
+
throw new api_types_1.AggregateSuiteError(results);
|
|
52
73
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
56
76
|
}
|
|
57
77
|
}
|
|
58
78
|
exports.Suite = Suite;
|
package/dist/variation.d.ts
CHANGED
|
@@ -4,7 +4,46 @@ export declare class Variation extends BenchmarkBase {
|
|
|
4
4
|
name: string;
|
|
5
5
|
environment: Partial<NodeJS.ProcessEnv>;
|
|
6
6
|
cliArgs: string[];
|
|
7
|
+
private context;
|
|
7
8
|
constructor(name: string);
|
|
9
|
+
/**
|
|
10
|
+
* Sets a value in the variation's context.
|
|
11
|
+
* This allows passing custom data to the action without using environment variables.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* new Variation('fast-impl')
|
|
16
|
+
* .withContext('implementation', fastProcessor)
|
|
17
|
+
* .withAction((variation) => {
|
|
18
|
+
* const impl = variation.get<DataProcessor>('implementation');
|
|
19
|
+
* impl.process(data);
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
withContext<T>(key: string, value: T): this;
|
|
24
|
+
/**
|
|
25
|
+
* Gets a value from the variation's context.
|
|
26
|
+
* Returns undefined if the key is not found.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* b.withAction((variation) => {
|
|
31
|
+
* const driver = variation.get<Driver>('driver');
|
|
32
|
+
* driver.connect();
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
get<T>(key: string): T | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Gets a value from the variation's context with a default value.
|
|
39
|
+
* Returns the default if the key is not found.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const iterations = variation.getOrDefault<number>('iterations', 10);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
getOrDefault<T>(key: string, defaultValue: T): T;
|
|
8
47
|
static FromEnvironmentVariables(variables: EnvironmentVariableOptions): Variation[];
|
|
9
48
|
/**
|
|
10
49
|
*
|
|
@@ -23,6 +62,29 @@ export declare class Variation extends BenchmarkBase {
|
|
|
23
62
|
* ]);
|
|
24
63
|
*/
|
|
25
64
|
static FromCliArgs(args: Array<string | string[]>): Variation[];
|
|
65
|
+
/**
|
|
66
|
+
* Creates variations with context values for a single key.
|
|
67
|
+
* Useful for swapping implementations or configurations.
|
|
68
|
+
*
|
|
69
|
+
* @param key The context key to set
|
|
70
|
+
* @param values Array of [name, value] tuples
|
|
71
|
+
* @returns An array of variations with context set
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const variations = Variation.FromContext('processor', [
|
|
76
|
+
* ['loop', loopProcessor],
|
|
77
|
+
* ['reduce', reduceProcessor],
|
|
78
|
+
* ]);
|
|
79
|
+
*
|
|
80
|
+
* benchmark.withVariations(variations);
|
|
81
|
+
* benchmark.withAction((variation) => {
|
|
82
|
+
* const processor = variation.get<DataProcessor>('processor');
|
|
83
|
+
* processor.process(data);
|
|
84
|
+
* });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
static FromContexts<T>(key: string, values: readonly (readonly [name: string, value: T])[]): Variation[];
|
|
26
88
|
withEnvironmentVariables(env: Partial<NodeJS.ProcessEnv>): this;
|
|
27
89
|
withEnvironmentVariable(name: string, value: string): this;
|
|
28
90
|
withCliArgs(...args: string[]): this;
|
package/dist/variation.js
CHANGED
|
@@ -4,11 +4,58 @@ exports.Variation = void 0;
|
|
|
4
4
|
const shared_api_1 = require("./shared-api");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
class Variation extends shared_api_1.BenchmarkBase {
|
|
7
|
+
name;
|
|
8
|
+
environment = {};
|
|
9
|
+
cliArgs = [];
|
|
10
|
+
context = new Map();
|
|
7
11
|
constructor(name) {
|
|
8
12
|
super();
|
|
9
13
|
this.name = name;
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sets a value in the variation's context.
|
|
17
|
+
* This allows passing custom data to the action without using environment variables.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* new Variation('fast-impl')
|
|
22
|
+
* .withContext('implementation', fastProcessor)
|
|
23
|
+
* .withAction((variation) => {
|
|
24
|
+
* const impl = variation.get<DataProcessor>('implementation');
|
|
25
|
+
* impl.process(data);
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
withContext(key, value) {
|
|
30
|
+
this.context.set(key, value);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Gets a value from the variation's context.
|
|
35
|
+
* Returns undefined if the key is not found.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* b.withAction((variation) => {
|
|
40
|
+
* const driver = variation.get<Driver>('driver');
|
|
41
|
+
* driver.connect();
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
get(key) {
|
|
46
|
+
return this.context.get(key);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Gets a value from the variation's context with a default value.
|
|
50
|
+
* Returns the default if the key is not found.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const iterations = variation.getOrDefault<number>('iterations', 10);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
getOrDefault(key, defaultValue) {
|
|
58
|
+
return this.context.get(key) ?? defaultValue;
|
|
12
59
|
}
|
|
13
60
|
static FromEnvironmentVariables(variables) {
|
|
14
61
|
const combinations = (0, utils_1.findCombinations)(variables.map(([name, values]) => values.map((value) => [name, value])));
|
|
@@ -49,8 +96,38 @@ class Variation extends shared_api_1.BenchmarkBase {
|
|
|
49
96
|
return new Variation(label).withCliArgs(...cliArgs);
|
|
50
97
|
});
|
|
51
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates variations with context values for a single key.
|
|
101
|
+
* Useful for swapping implementations or configurations.
|
|
102
|
+
*
|
|
103
|
+
* @param key The context key to set
|
|
104
|
+
* @param values Array of [name, value] tuples
|
|
105
|
+
* @returns An array of variations with context set
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const variations = Variation.FromContext('processor', [
|
|
110
|
+
* ['loop', loopProcessor],
|
|
111
|
+
* ['reduce', reduceProcessor],
|
|
112
|
+
* ]);
|
|
113
|
+
*
|
|
114
|
+
* benchmark.withVariations(variations);
|
|
115
|
+
* benchmark.withAction((variation) => {
|
|
116
|
+
* const processor = variation.get<DataProcessor>('processor');
|
|
117
|
+
* processor.process(data);
|
|
118
|
+
* });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
static FromContexts(key, values) {
|
|
122
|
+
return values.map(([name, value]) => {
|
|
123
|
+
return new Variation(name).withContext(key, value);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
52
126
|
withEnvironmentVariables(env) {
|
|
53
|
-
this.environment =
|
|
127
|
+
this.environment = {
|
|
128
|
+
...this.environment,
|
|
129
|
+
...env,
|
|
130
|
+
};
|
|
54
131
|
return this;
|
|
55
132
|
}
|
|
56
133
|
withEnvironmentVariable(name, value) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flexi-bench",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -11,18 +11,22 @@
|
|
|
11
11
|
"test": "node --import tsx --test './src/**/*.spec.ts'",
|
|
12
12
|
"test:watch": "node --import tsx --test --watch './src/**/*.spec.ts'",
|
|
13
13
|
"build": "tsc -p tsconfig.json",
|
|
14
|
-
"format": "prettier --write src"
|
|
14
|
+
"format": "prettier --write src",
|
|
15
|
+
"prepare": "patch-package && nx build flexi-bench"
|
|
15
16
|
},
|
|
16
17
|
"author": "",
|
|
17
18
|
"license": "MIT",
|
|
18
19
|
"devDependencies": {
|
|
20
|
+
"@nx-dotnet/nx-ghpages": "^2.3.0",
|
|
19
21
|
"@nx/js": "^19.4.2",
|
|
20
22
|
"@swc-node/register": "~1.9.1",
|
|
21
23
|
"@swc/core": "~1.5.7",
|
|
22
24
|
"@swc/helpers": "~0.5.11",
|
|
23
25
|
"@types/cli-progress": "^3.11.6",
|
|
26
|
+
"@types/is-ci": "^3.0.4",
|
|
24
27
|
"@types/node": "^20.14.10",
|
|
25
28
|
"nx": "19.4.2",
|
|
29
|
+
"patch-package": "^8.0.0",
|
|
26
30
|
"prettier": "^3.3.2",
|
|
27
31
|
"ts-node": "^10.9.2",
|
|
28
32
|
"tsx": "^4.16.2",
|
|
@@ -31,6 +35,7 @@
|
|
|
31
35
|
},
|
|
32
36
|
"dependencies": {
|
|
33
37
|
"cli-progress": "^3.12.0",
|
|
38
|
+
"is-ci": "^4.1.0",
|
|
34
39
|
"markdown-factory": "^0.0.6"
|
|
35
40
|
},
|
|
36
41
|
"nx": {},
|