overtake 0.1.2 → 1.0.0-rc.2
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/README.md +76 -82
- package/bin/overtake.js +2 -0
- package/build/__tests__/runner.d.ts +1 -0
- package/build/benchmark.cjs +237 -0
- package/build/benchmark.cjs.map +1 -0
- package/build/benchmark.d.ts +64 -0
- package/build/benchmark.js +189 -0
- package/build/benchmark.js.map +1 -0
- package/build/cli.cjs +149 -0
- package/build/cli.cjs.map +1 -0
- package/build/cli.d.ts +1 -0
- package/build/cli.js +104 -0
- package/build/cli.js.map +1 -0
- package/build/executor.cjs +68 -0
- package/build/executor.cjs.map +1 -0
- package/build/executor.d.ts +10 -0
- package/build/executor.js +58 -0
- package/build/executor.js.map +1 -0
- package/build/index.cjs +20 -0
- package/build/index.cjs.map +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +3 -0
- package/build/index.js.map +1 -0
- package/build/queue.cjs +48 -0
- package/build/queue.cjs.map +1 -0
- package/build/queue.d.ts +3 -0
- package/build/queue.js +38 -0
- package/build/queue.js.map +1 -0
- package/build/reporter.cjs +175 -0
- package/build/reporter.cjs.map +1 -0
- package/build/reporter.d.ts +11 -0
- package/build/reporter.js +157 -0
- package/build/reporter.js.map +1 -0
- package/build/runner.cjs +92 -0
- package/build/runner.cjs.map +1 -0
- package/build/runner.d.ts +2 -0
- package/build/runner.js +82 -0
- package/build/runner.js.map +1 -0
- package/build/types.cjs +48 -0
- package/build/types.cjs.map +1 -0
- package/build/types.d.ts +59 -0
- package/build/types.js +21 -0
- package/build/types.js.map +1 -0
- package/build/utils.cjs +100 -0
- package/build/utils.cjs.map +1 -0
- package/build/utils.d.ts +20 -0
- package/build/utils.js +67 -0
- package/build/utils.js.map +1 -0
- package/build/worker.cjs +29 -0
- package/build/worker.cjs.map +1 -0
- package/build/worker.d.ts +1 -0
- package/build/worker.js +25 -0
- package/build/worker.js.map +1 -0
- package/package.json +15 -13
- package/src/__tests__/runner.ts +34 -0
- package/src/benchmark.ts +231 -0
- package/src/cli.ts +114 -0
- package/src/executor.ts +73 -0
- package/src/index.ts +6 -0
- package/src/queue.ts +42 -0
- package/src/reporter.ts +139 -0
- package/src/runner.ts +111 -0
- package/src/types.ts +72 -0
- package/src/utils.ts +65 -0
- package/src/worker.ts +46 -0
- package/tsconfig.json +17 -0
- package/cli.js +0 -70
- package/index.d.ts +0 -56
- package/index.js +0 -303
- package/runner.js +0 -3
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { cpus } from 'node:os';
|
|
2
|
+
import { createExecutor } from "./executor.js";
|
|
3
|
+
import { DEFAULT_CYCLES } from "./types.js";
|
|
4
|
+
export const DEFAULT_WORKERS = cpus().length;
|
|
5
|
+
export const AsyncFunction = (async ()=>{}).constructor;
|
|
6
|
+
export const DEFAULT_REPORT_TYPES = [
|
|
7
|
+
'ops'
|
|
8
|
+
];
|
|
9
|
+
export class MeasureContext {
|
|
10
|
+
title;
|
|
11
|
+
run;
|
|
12
|
+
pre;
|
|
13
|
+
post;
|
|
14
|
+
constructor(title, run){
|
|
15
|
+
this.title = title;
|
|
16
|
+
this.run = run;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class Measure {
|
|
20
|
+
#ctx;
|
|
21
|
+
constructor(ctx){
|
|
22
|
+
this.#ctx = ctx;
|
|
23
|
+
}
|
|
24
|
+
pre(fn) {
|
|
25
|
+
this.#ctx.pre = fn;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
post(fn) {
|
|
29
|
+
this.#ctx.post = fn;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class TargetContext {
|
|
34
|
+
title;
|
|
35
|
+
setup;
|
|
36
|
+
teardown;
|
|
37
|
+
measures;
|
|
38
|
+
constructor(title, setup){
|
|
39
|
+
this.title = title;
|
|
40
|
+
this.setup = setup;
|
|
41
|
+
this.measures = [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export class Target {
|
|
45
|
+
#ctx;
|
|
46
|
+
constructor(ctx){
|
|
47
|
+
this.#ctx = ctx;
|
|
48
|
+
}
|
|
49
|
+
teardown(fn) {
|
|
50
|
+
this.#ctx.teardown = fn;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
measure(title, run) {
|
|
54
|
+
const measure = new MeasureContext(title, run);
|
|
55
|
+
this.#ctx.measures.push(measure);
|
|
56
|
+
return new Measure(measure);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class FeedContext {
|
|
60
|
+
title;
|
|
61
|
+
fn;
|
|
62
|
+
constructor(title, fn){
|
|
63
|
+
this.title = title;
|
|
64
|
+
this.fn = fn;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export class Benchmark {
|
|
68
|
+
#targets = [];
|
|
69
|
+
#feeds = [];
|
|
70
|
+
#executed = false;
|
|
71
|
+
static create(title, fn) {
|
|
72
|
+
if (fn) {
|
|
73
|
+
return new Benchmark(title, fn);
|
|
74
|
+
} else {
|
|
75
|
+
return new Benchmark(title);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
constructor(title, fn){
|
|
79
|
+
if (fn) {
|
|
80
|
+
this.feed(title, fn);
|
|
81
|
+
} else {
|
|
82
|
+
this.feed(title);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
feed(title, fn) {
|
|
86
|
+
const self = this;
|
|
87
|
+
self.#feeds.push(fn ? new FeedContext(title, fn) : new FeedContext(title));
|
|
88
|
+
return self;
|
|
89
|
+
}
|
|
90
|
+
target(title, setup) {
|
|
91
|
+
const target = new TargetContext(title, setup);
|
|
92
|
+
this.#targets.push(target);
|
|
93
|
+
return new Target(target);
|
|
94
|
+
}
|
|
95
|
+
async execute({ workers = DEFAULT_WORKERS, warmupCycles = 20, maxCycles = DEFAULT_CYCLES, minCycles = 50, absThreshold = 1_000, relThreshold = 0.02, reportTypes = DEFAULT_REPORT_TYPES }) {
|
|
96
|
+
if (this.#executed) {
|
|
97
|
+
throw new Error("Benchmark is executed and can't be reused");
|
|
98
|
+
}
|
|
99
|
+
this.#executed = true;
|
|
100
|
+
const executor = createExecutor({
|
|
101
|
+
workers,
|
|
102
|
+
warmupCycles,
|
|
103
|
+
maxCycles,
|
|
104
|
+
minCycles,
|
|
105
|
+
absThreshold,
|
|
106
|
+
relThreshold,
|
|
107
|
+
reportTypes
|
|
108
|
+
});
|
|
109
|
+
const reports = [];
|
|
110
|
+
for (const target of this.#targets){
|
|
111
|
+
const targetReport = {
|
|
112
|
+
target: target.title,
|
|
113
|
+
measures: []
|
|
114
|
+
};
|
|
115
|
+
for (const measure of target.measures){
|
|
116
|
+
const measureReport = {
|
|
117
|
+
measure: measure.title,
|
|
118
|
+
feeds: []
|
|
119
|
+
};
|
|
120
|
+
for (const feed of this.#feeds){
|
|
121
|
+
const data = await feed.fn?.();
|
|
122
|
+
executor.push({
|
|
123
|
+
setup: target.setup,
|
|
124
|
+
teardown: target.teardown,
|
|
125
|
+
pre: measure.pre,
|
|
126
|
+
run: measure.run,
|
|
127
|
+
post: measure.post,
|
|
128
|
+
data
|
|
129
|
+
}).then((data)=>{
|
|
130
|
+
measureReport.feeds.push({
|
|
131
|
+
feed: feed.title,
|
|
132
|
+
data
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
targetReport.measures.push(measureReport);
|
|
137
|
+
}
|
|
138
|
+
reports.push(targetReport);
|
|
139
|
+
}
|
|
140
|
+
await executor.drain();
|
|
141
|
+
executor.kill();
|
|
142
|
+
return reports;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export const printSimpleReports = (reports)=>{
|
|
146
|
+
for (const report of reports){
|
|
147
|
+
for (const { measure, feeds } of report.measures){
|
|
148
|
+
console.group('\n', report.target, measure);
|
|
149
|
+
for (const { feed, data } of feeds){
|
|
150
|
+
const output = Object.entries(data).map(([key, report])=>`${key}: ${report.toString()}`).join('; ');
|
|
151
|
+
console.log(feed, output);
|
|
152
|
+
}
|
|
153
|
+
console.groupEnd();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
export const printTableReports = (reports)=>{
|
|
158
|
+
for (const report of reports){
|
|
159
|
+
for (const { measure, feeds } of report.measures){
|
|
160
|
+
console.log('\n', report.target, measure);
|
|
161
|
+
const table = {};
|
|
162
|
+
for (const { feed, data } of feeds){
|
|
163
|
+
table[feed] = Object.fromEntries(Object.entries(data).map(([key, report])=>[
|
|
164
|
+
key,
|
|
165
|
+
report.toString()
|
|
166
|
+
]));
|
|
167
|
+
}
|
|
168
|
+
console.table(table);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
export const printJSONReports = (reports, padding)=>{
|
|
173
|
+
const output = {};
|
|
174
|
+
for (const report of reports){
|
|
175
|
+
for (const { measure, feeds } of report.measures){
|
|
176
|
+
const row = {};
|
|
177
|
+
for (const { feed, data } of feeds){
|
|
178
|
+
row[feed] = Object.fromEntries(Object.entries(data).map(([key, report])=>[
|
|
179
|
+
key,
|
|
180
|
+
report.toString()
|
|
181
|
+
]));
|
|
182
|
+
}
|
|
183
|
+
output[`${report.target} ${measure}`] = row;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
console.log(JSON.stringify(output, null, padding));
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/benchmark.ts"],"sourcesContent":["import { cpus } from 'node:os';\nimport { createExecutor, ExecutorOptions, ExecutorReport } from './executor.js';\nimport { MaybePromise, StepFn, SetupFn, TeardownFn, FeedFn, ReportType, ReportTypeList, DEFAULT_CYCLES } from './types.js';\n\nexport const DEFAULT_WORKERS = cpus().length;\n\nexport const AsyncFunction = (async () => {}).constructor;\n\nexport interface TargetReport<R extends ReportTypeList> {\n target: string;\n measures: MeasureReport<R>[];\n}\n\nexport interface MeasureReport<R extends ReportTypeList> {\n measure: string;\n feeds: FeedReport<R>[];\n}\n\nexport interface FeedReport<R extends ReportTypeList> {\n feed: string;\n data: ExecutorReport<R>;\n}\n\nexport const DEFAULT_REPORT_TYPES = ['ops'] as const;\nexport type DefaultReportTypes = (typeof DEFAULT_REPORT_TYPES)[number];\n\nexport class MeasureContext<TContext, TInput> {\n public pre?: StepFn<TContext, TInput>;\n public post?: StepFn<TContext, TInput>;\n\n constructor(\n public title: string,\n public run: StepFn<TContext, TInput>,\n ) {}\n}\n\nexport class Measure<TContext, TInput> {\n #ctx: MeasureContext<TContext, TInput>;\n\n constructor(ctx: MeasureContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n\n pre(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.pre = fn;\n return this;\n }\n post(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.post = fn;\n return this;\n }\n}\n\nexport class TargetContext<TContext, TInput> {\n public teardown?: TeardownFn<TContext>;\n public measures: MeasureContext<TContext, TInput>[] = [];\n\n constructor(\n readonly title: string,\n readonly setup?: SetupFn<MaybePromise<TContext>>,\n ) {}\n}\n\nexport class Target<TContext, TInput> {\n #ctx: TargetContext<TContext, TInput>;\n\n constructor(ctx: TargetContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n teardown(fn: TeardownFn<TContext>): Target<TContext, TInput> {\n this.#ctx.teardown = fn;\n\n return this;\n }\n measure(title: string, run: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n const measure = new MeasureContext(title, run);\n this.#ctx.measures.push(measure);\n\n return new Measure(measure);\n }\n}\n\nexport class FeedContext<TInput> {\n constructor(\n readonly title: string,\n readonly fn?: FeedFn<TInput>,\n ) {}\n}\n\nexport class Benchmark<TInput> {\n #targets: TargetContext<unknown, TInput>[] = [];\n #feeds: FeedContext<TInput>[] = [];\n #executed = false;\n\n static create(title: string): Benchmark<void>;\n static create<I>(title: string, fn: FeedFn<I>): Benchmark<I>;\n static create<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<I> {\n if (fn) {\n return new Benchmark(title, fn);\n } else {\n return new Benchmark(title);\n }\n }\n\n constructor(title: string);\n constructor(title: string, fn: FeedFn<TInput>);\n constructor(title: string, fn?: FeedFn<TInput> | undefined) {\n if (fn) {\n this.feed(title, fn);\n } else {\n this.feed(title);\n }\n }\n\n feed(title: string): Benchmark<TInput | void>;\n feed<I>(title: string, fn: FeedFn<I>): Benchmark<TInput | I>;\n feed<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<TInput | I> {\n const self = this as Benchmark<TInput | I>;\n self.#feeds.push(fn ? new FeedContext(title, fn) : new FeedContext(title));\n\n return self;\n }\n\n target<TContext>(title: string): Target<void, TInput>;\n target<TContext>(title: string, setup: SetupFn<Awaited<TContext>>): Target<TContext, TInput>;\n target<TContext>(title: string, setup?: SetupFn<Awaited<TContext>> | undefined): Target<TContext, TInput> {\n const target = new TargetContext<TContext, TInput>(title, setup);\n this.#targets.push(target as TargetContext<unknown, TInput>);\n\n return new Target<TContext, TInput>(target);\n }\n\n async execute<R extends readonly ReportType[] = typeof DEFAULT_REPORT_TYPES>({\n workers = DEFAULT_WORKERS,\n warmupCycles = 20,\n maxCycles = DEFAULT_CYCLES,\n minCycles = 50,\n absThreshold = 1_000,\n relThreshold = 0.02,\n reportTypes = DEFAULT_REPORT_TYPES as unknown as R,\n }: ExecutorOptions<R>): Promise<TargetReport<R>[]> {\n if (this.#executed) {\n throw new Error(\"Benchmark is executed and can't be reused\");\n }\n this.#executed = true;\n\n const executor = createExecutor<unknown, TInput, R>({\n workers,\n warmupCycles,\n maxCycles,\n minCycles,\n absThreshold,\n relThreshold,\n reportTypes,\n });\n\n const reports: TargetReport<R>[] = [];\n for (const target of this.#targets) {\n const targetReport: TargetReport<R> = { target: target.title, measures: [] };\n for (const measure of target.measures) {\n const measureReport: MeasureReport<R> = { measure: measure.title, feeds: [] };\n for (const feed of this.#feeds) {\n const data = await feed.fn?.();\n executor\n .push<ExecutorReport<R>>({\n setup: target.setup,\n teardown: target.teardown,\n pre: measure.pre,\n run: measure.run,\n post: measure.post,\n data,\n })\n .then((data) => {\n measureReport.feeds.push({\n feed: feed.title,\n data,\n });\n });\n }\n targetReport.measures.push(measureReport);\n }\n reports.push(targetReport);\n }\n await executor.drain();\n executor.kill();\n\n return reports;\n }\n}\n\nexport const printSimpleReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.group('\\n', report.target, measure);\n for (const { feed, data } of feeds) {\n const output = Object.entries(data)\n .map(([key, report]) => `${key}: ${report.toString()}`)\n .join('; ');\n console.log(feed, output);\n }\n console.groupEnd();\n }\n }\n};\n\nexport const printTableReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log('\\n', report.target, measure);\n const table: Record<string, unknown> = {};\n for (const { feed, data } of feeds) {\n table[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n console.table(table);\n }\n }\n};\n\nexport const printJSONReports = <R extends ReportTypeList>(reports: TargetReport<R>[], padding?: number) => {\n const output = {} as Record<string, Record<string, Record<string, string>>>;\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n const row = {} as Record<string, Record<string, string>>;\n for (const { feed, data } of feeds) {\n row[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n output[`${report.target} ${measure}`] = row;\n }\n }\n console.log(JSON.stringify(output, null, padding));\n};\n"],"names":["cpus","createExecutor","DEFAULT_CYCLES","DEFAULT_WORKERS","length","AsyncFunction","constructor","DEFAULT_REPORT_TYPES","MeasureContext","pre","post","title","run","Measure","ctx","fn","TargetContext","teardown","measures","setup","Target","measure","push","FeedContext","Benchmark","create","feed","self","target","execute","workers","warmupCycles","maxCycles","minCycles","absThreshold","relThreshold","reportTypes","Error","executor","reports","targetReport","measureReport","feeds","data","then","drain","kill","printSimpleReports","report","console","group","output","Object","entries","map","key","toString","join","log","groupEnd","printTableReports","table","fromEntries","printJSONReports","padding","row","JSON","stringify"],"mappings":"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"}
|
package/build/cli.cjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
const _nodemodule = require("node:module");
|
|
6
|
+
const _nodevm = require("node:vm");
|
|
7
|
+
const _promises = require("node:fs/promises");
|
|
8
|
+
const _core = require("@swc/core");
|
|
9
|
+
const _commander = require("commander");
|
|
10
|
+
const _glob = require("glob");
|
|
11
|
+
const _benchmarkcjs = require("./benchmark.cjs");
|
|
12
|
+
const _typescjs = require("./types.cjs");
|
|
13
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
14
|
+
if (typeof WeakMap !== "function") return null;
|
|
15
|
+
var cacheBabelInterop = new WeakMap();
|
|
16
|
+
var cacheNodeInterop = new WeakMap();
|
|
17
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
18
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
19
|
+
})(nodeInterop);
|
|
20
|
+
}
|
|
21
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
22
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
26
|
+
return {
|
|
27
|
+
default: obj
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
31
|
+
if (cache && cache.has(obj)) {
|
|
32
|
+
return cache.get(obj);
|
|
33
|
+
}
|
|
34
|
+
var newObj = {
|
|
35
|
+
__proto__: null
|
|
36
|
+
};
|
|
37
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
38
|
+
for(var key in obj){
|
|
39
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
40
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
41
|
+
if (desc && (desc.get || desc.set)) {
|
|
42
|
+
Object.defineProperty(newObj, key, desc);
|
|
43
|
+
} else {
|
|
44
|
+
newObj[key] = obj[key];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
newObj.default = obj;
|
|
49
|
+
if (cache) {
|
|
50
|
+
cache.set(obj, newObj);
|
|
51
|
+
}
|
|
52
|
+
return newObj;
|
|
53
|
+
}
|
|
54
|
+
const require1 = (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString());
|
|
55
|
+
const { name, description, version } = require1('../package.json');
|
|
56
|
+
const commander = new _commander.Command();
|
|
57
|
+
const transpile = async (code)=>{
|
|
58
|
+
const ast = await (0, _core.parse)(code, {
|
|
59
|
+
syntax: 'typescript',
|
|
60
|
+
dynamicImport: true,
|
|
61
|
+
target: 'esnext'
|
|
62
|
+
});
|
|
63
|
+
const output = await (0, _core.print)(ast, {
|
|
64
|
+
module: {
|
|
65
|
+
type: 'es6'
|
|
66
|
+
},
|
|
67
|
+
jsc: {
|
|
68
|
+
target: 'esnext',
|
|
69
|
+
parser: {
|
|
70
|
+
syntax: 'typescript'
|
|
71
|
+
},
|
|
72
|
+
experimental: {}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return output.code;
|
|
76
|
+
};
|
|
77
|
+
commander.name(name).description(description).version(version).argument('<path>', 'glob pattern to find benchmarks').addOption(new _commander.Option('-r, --report-types [reportTypes...]', 'statistic types to include in the report').choices(_typescjs.REPORT_TYPES).default(_benchmarkcjs.DEFAULT_REPORT_TYPES)).addOption(new _commander.Option('-w, --workers [workers]', 'number of concurent workers').default(_benchmarkcjs.DEFAULT_WORKERS).argParser(parseInt)).addOption(new _commander.Option('-f, --format [format]', 'output format').default('simple').choices([
|
|
78
|
+
'simple',
|
|
79
|
+
'json',
|
|
80
|
+
'pjson',
|
|
81
|
+
'table'
|
|
82
|
+
])).addOption(new _commander.Option('--abs-threshold [absThreshold]', 'absolute error threshold in nanoseconds').argParser(parseInt)).addOption(new _commander.Option('--rel-threshold [relThreshold]', 'relative error threshold (fraction between 0 and 1)').argParser(parseInt)).addOption(new _commander.Option('--warmup-cycles [warmupCycles]', 'number of warmup cycles before measuring').argParser(parseInt)).addOption(new _commander.Option('--max-cycles [maxCycles]', 'maximum measurement cycles per feed').argParser(parseInt)).addOption(new _commander.Option('--min-cycles [minCycles]', 'minimum measurement cycles per feed').argParser(parseInt)).action(async (path, executeOptions)=>{
|
|
83
|
+
const files = await (0, _glob.glob)(path, {
|
|
84
|
+
absolute: true,
|
|
85
|
+
cwd: process.cwd()
|
|
86
|
+
}).catch(()=>[]);
|
|
87
|
+
for (const file of files){
|
|
88
|
+
const stats = await (0, _promises.stat)(file).catch(()=>false);
|
|
89
|
+
if (stats && stats.isFile()) {
|
|
90
|
+
const content = await (0, _promises.readFile)(file, 'utf8');
|
|
91
|
+
const code = await transpile(content);
|
|
92
|
+
let instance;
|
|
93
|
+
const benchmark = (...args)=>{
|
|
94
|
+
if (instance) {
|
|
95
|
+
throw new Error('Only one benchmark per file is supported');
|
|
96
|
+
}
|
|
97
|
+
instance = _benchmarkcjs.Benchmark.create(...args);
|
|
98
|
+
return instance;
|
|
99
|
+
};
|
|
100
|
+
const script = new _nodevm.SourceTextModule(code, {
|
|
101
|
+
context: (0, _nodevm.createContext)({
|
|
102
|
+
benchmark
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
const imports = new Map();
|
|
106
|
+
await script.link(async (specifier, referencingModule)=>{
|
|
107
|
+
if (imports.has(specifier)) {
|
|
108
|
+
return imports.get(specifier);
|
|
109
|
+
}
|
|
110
|
+
const mod = await Promise.resolve(_nodemodule.Module.isBuiltin(specifier) ? specifier : require1.resolve(specifier)).then((p)=>/*#__PURE__*/ _interop_require_wildcard(require(p)));
|
|
111
|
+
const exportNames = Object.keys(mod);
|
|
112
|
+
const imported = new _nodevm.SyntheticModule(exportNames, ()=>{
|
|
113
|
+
exportNames.forEach((key)=>imported.setExport(key, mod[key]));
|
|
114
|
+
}, {
|
|
115
|
+
identifier: specifier,
|
|
116
|
+
context: referencingModule.context
|
|
117
|
+
});
|
|
118
|
+
imports.set(specifier, imported);
|
|
119
|
+
return imported;
|
|
120
|
+
});
|
|
121
|
+
await script.evaluate();
|
|
122
|
+
if (instance) {
|
|
123
|
+
const reports = await instance.execute(executeOptions);
|
|
124
|
+
switch(executeOptions.format){
|
|
125
|
+
case 'json':
|
|
126
|
+
{
|
|
127
|
+
(0, _benchmarkcjs.printJSONReports)(reports);
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case 'pjson':
|
|
131
|
+
{
|
|
132
|
+
(0, _benchmarkcjs.printJSONReports)(reports, 2);
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
case 'table':
|
|
136
|
+
{
|
|
137
|
+
(0, _benchmarkcjs.printTableReports)(reports);
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
(0, _benchmarkcjs.printSimpleReports)(reports);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
commander.parse(process.argv);
|
|
148
|
+
|
|
149
|
+
//# sourceMappingURL=cli.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { createRequire, Module } from 'node:module';\nimport { SyntheticModule, createContext, SourceTextModule, Module as VMModule } from 'node:vm';\nimport { stat, readFile } from 'node:fs/promises';\nimport { parse, print } from '@swc/core';\nimport { Command, Option } from 'commander';\nimport { glob } from 'glob';\nimport { Benchmark, printTableReports, printJSONReports, printSimpleReports, DEFAULT_REPORT_TYPES, DEFAULT_WORKERS } from './benchmark.js';\nimport { REPORT_TYPES } from './types.js';\n\nconst require = createRequire(import.meta.url);\nconst { name, description, version } = require('../package.json');\n\nconst commander = new Command();\n\nconst transpile = async (code: string): Promise<string> => {\n const ast = await parse(code, {\n syntax: 'typescript',\n dynamicImport: true,\n target: 'esnext',\n });\n\n const output = await print(ast, {\n module: {\n type: 'es6',\n },\n jsc: {\n target: 'esnext',\n parser: {\n syntax: 'typescript',\n },\n experimental: {},\n },\n });\n return output.code;\n};\n\ncommander\n .name(name)\n .description(description)\n .version(version)\n .argument('<path>', 'glob pattern to find benchmarks')\n .addOption(new Option('-r, --report-types [reportTypes...]', 'statistic types to include in the report').choices(REPORT_TYPES).default(DEFAULT_REPORT_TYPES))\n .addOption(new Option('-w, --workers [workers]', 'number of concurent workers').default(DEFAULT_WORKERS).argParser(parseInt))\n .addOption(new Option('-f, --format [format]', 'output format').default('simple').choices(['simple', 'json', 'pjson', 'table']))\n .addOption(new Option('--abs-threshold [absThreshold]', 'absolute error threshold in nanoseconds').argParser(parseInt))\n .addOption(new Option('--rel-threshold [relThreshold]', 'relative error threshold (fraction between 0 and 1)').argParser(parseInt))\n .addOption(new Option('--warmup-cycles [warmupCycles]', 'number of warmup cycles before measuring').argParser(parseInt))\n .addOption(new Option('--max-cycles [maxCycles]', 'maximum measurement cycles per feed').argParser(parseInt))\n .addOption(new Option('--min-cycles [minCycles]', 'minimum measurement cycles per feed').argParser(parseInt))\n .action(async (path, executeOptions) => {\n const files = await glob(path, { absolute: true, cwd: process.cwd() }).catch(() => []);\n for (const file of files) {\n const stats = await stat(file).catch(() => false as const);\n if (stats && stats.isFile()) {\n const content = await readFile(file, 'utf8');\n const code = await transpile(content);\n let instance: Benchmark<unknown> | undefined;\n const benchmark = (...args: Parameters<(typeof Benchmark)['create']>) => {\n if (instance) {\n throw new Error('Only one benchmark per file is supported');\n }\n instance = Benchmark.create(...args);\n return instance;\n };\n const script = new SourceTextModule(code, {\n context: createContext({ benchmark }),\n });\n const imports = new Map();\n await script.link(async (specifier: string, referencingModule) => {\n if (imports.has(specifier)) {\n return imports.get(specifier);\n }\n const mod = await import(Module.isBuiltin(specifier) ? specifier : require.resolve(specifier));\n const exportNames = Object.keys(mod);\n const imported = new SyntheticModule(\n exportNames,\n () => {\n exportNames.forEach((key) => imported.setExport(key, mod[key]));\n },\n { identifier: specifier, context: referencingModule.context },\n );\n\n imports.set(specifier, imported);\n return imported;\n });\n await script.evaluate();\n\n if (instance) {\n const reports = await instance.execute(executeOptions);\n switch (executeOptions.format) {\n case 'json':\n {\n printJSONReports(reports);\n }\n break;\n case 'pjson':\n {\n printJSONReports(reports, 2);\n }\n break;\n case 'table':\n {\n printTableReports(reports);\n }\n break;\n default:\n printSimpleReports(reports);\n }\n }\n }\n }\n });\n\ncommander.parse(process.argv);\n"],"names":["require","createRequire","name","description","version","commander","Command","transpile","code","ast","parse","syntax","dynamicImport","target","output","print","module","type","jsc","parser","experimental","argument","addOption","Option","choices","REPORT_TYPES","default","DEFAULT_REPORT_TYPES","DEFAULT_WORKERS","argParser","parseInt","action","path","executeOptions","files","glob","absolute","cwd","process","catch","file","stats","stat","isFile","content","readFile","instance","benchmark","args","Error","Benchmark","create","script","SourceTextModule","context","createContext","imports","Map","link","specifier","referencingModule","has","get","mod","Module","isBuiltin","resolve","exportNames","Object","keys","imported","SyntheticModule","forEach","key","setExport","identifier","set","evaluate","reports","execute","format","printJSONReports","printTableReports","printSimpleReports","argv"],"mappings":"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"}
|
package/build/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/cli.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRequire, Module } from 'node:module';
|
|
2
|
+
import { SyntheticModule, createContext, SourceTextModule } from 'node:vm';
|
|
3
|
+
import { stat, readFile } from 'node:fs/promises';
|
|
4
|
+
import { parse, print } from '@swc/core';
|
|
5
|
+
import { Command, Option } from 'commander';
|
|
6
|
+
import { glob } from 'glob';
|
|
7
|
+
import { Benchmark, printTableReports, printJSONReports, printSimpleReports, DEFAULT_REPORT_TYPES, DEFAULT_WORKERS } from "./benchmark.js";
|
|
8
|
+
import { REPORT_TYPES } from "./types.js";
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const { name, description, version } = require('../package.json');
|
|
11
|
+
const commander = new Command();
|
|
12
|
+
const transpile = async (code)=>{
|
|
13
|
+
const ast = await parse(code, {
|
|
14
|
+
syntax: 'typescript',
|
|
15
|
+
dynamicImport: true,
|
|
16
|
+
target: 'esnext'
|
|
17
|
+
});
|
|
18
|
+
const output = await print(ast, {
|
|
19
|
+
module: {
|
|
20
|
+
type: 'es6'
|
|
21
|
+
},
|
|
22
|
+
jsc: {
|
|
23
|
+
target: 'esnext',
|
|
24
|
+
parser: {
|
|
25
|
+
syntax: 'typescript'
|
|
26
|
+
},
|
|
27
|
+
experimental: {}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return output.code;
|
|
31
|
+
};
|
|
32
|
+
commander.name(name).description(description).version(version).argument('<path>', 'glob pattern to find benchmarks').addOption(new Option('-r, --report-types [reportTypes...]', 'statistic types to include in the report').choices(REPORT_TYPES).default(DEFAULT_REPORT_TYPES)).addOption(new Option('-w, --workers [workers]', 'number of concurent workers').default(DEFAULT_WORKERS).argParser(parseInt)).addOption(new Option('-f, --format [format]', 'output format').default('simple').choices([
|
|
33
|
+
'simple',
|
|
34
|
+
'json',
|
|
35
|
+
'pjson',
|
|
36
|
+
'table'
|
|
37
|
+
])).addOption(new Option('--abs-threshold [absThreshold]', 'absolute error threshold in nanoseconds').argParser(parseInt)).addOption(new Option('--rel-threshold [relThreshold]', 'relative error threshold (fraction between 0 and 1)').argParser(parseInt)).addOption(new Option('--warmup-cycles [warmupCycles]', 'number of warmup cycles before measuring').argParser(parseInt)).addOption(new Option('--max-cycles [maxCycles]', 'maximum measurement cycles per feed').argParser(parseInt)).addOption(new Option('--min-cycles [minCycles]', 'minimum measurement cycles per feed').argParser(parseInt)).action(async (path, executeOptions)=>{
|
|
38
|
+
const files = await glob(path, {
|
|
39
|
+
absolute: true,
|
|
40
|
+
cwd: process.cwd()
|
|
41
|
+
}).catch(()=>[]);
|
|
42
|
+
for (const file of files){
|
|
43
|
+
const stats = await stat(file).catch(()=>false);
|
|
44
|
+
if (stats && stats.isFile()) {
|
|
45
|
+
const content = await readFile(file, 'utf8');
|
|
46
|
+
const code = await transpile(content);
|
|
47
|
+
let instance;
|
|
48
|
+
const benchmark = (...args)=>{
|
|
49
|
+
if (instance) {
|
|
50
|
+
throw new Error('Only one benchmark per file is supported');
|
|
51
|
+
}
|
|
52
|
+
instance = Benchmark.create(...args);
|
|
53
|
+
return instance;
|
|
54
|
+
};
|
|
55
|
+
const script = new SourceTextModule(code, {
|
|
56
|
+
context: createContext({
|
|
57
|
+
benchmark
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
const imports = new Map();
|
|
61
|
+
await script.link(async (specifier, referencingModule)=>{
|
|
62
|
+
if (imports.has(specifier)) {
|
|
63
|
+
return imports.get(specifier);
|
|
64
|
+
}
|
|
65
|
+
const mod = await import(Module.isBuiltin(specifier) ? specifier : require.resolve(specifier));
|
|
66
|
+
const exportNames = Object.keys(mod);
|
|
67
|
+
const imported = new SyntheticModule(exportNames, ()=>{
|
|
68
|
+
exportNames.forEach((key)=>imported.setExport(key, mod[key]));
|
|
69
|
+
}, {
|
|
70
|
+
identifier: specifier,
|
|
71
|
+
context: referencingModule.context
|
|
72
|
+
});
|
|
73
|
+
imports.set(specifier, imported);
|
|
74
|
+
return imported;
|
|
75
|
+
});
|
|
76
|
+
await script.evaluate();
|
|
77
|
+
if (instance) {
|
|
78
|
+
const reports = await instance.execute(executeOptions);
|
|
79
|
+
switch(executeOptions.format){
|
|
80
|
+
case 'json':
|
|
81
|
+
{
|
|
82
|
+
printJSONReports(reports);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case 'pjson':
|
|
86
|
+
{
|
|
87
|
+
printJSONReports(reports, 2);
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
case 'table':
|
|
91
|
+
{
|
|
92
|
+
printTableReports(reports);
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
printSimpleReports(reports);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
commander.parse(process.argv);
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=cli.js.map
|
package/build/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { createRequire, Module } from 'node:module';\nimport { SyntheticModule, createContext, SourceTextModule, Module as VMModule } from 'node:vm';\nimport { stat, readFile } from 'node:fs/promises';\nimport { parse, print } from '@swc/core';\nimport { Command, Option } from 'commander';\nimport { glob } from 'glob';\nimport { Benchmark, printTableReports, printJSONReports, printSimpleReports, DEFAULT_REPORT_TYPES, DEFAULT_WORKERS } from './benchmark.js';\nimport { REPORT_TYPES } from './types.js';\n\nconst require = createRequire(import.meta.url);\nconst { name, description, version } = require('../package.json');\n\nconst commander = new Command();\n\nconst transpile = async (code: string): Promise<string> => {\n const ast = await parse(code, {\n syntax: 'typescript',\n dynamicImport: true,\n target: 'esnext',\n });\n\n const output = await print(ast, {\n module: {\n type: 'es6',\n },\n jsc: {\n target: 'esnext',\n parser: {\n syntax: 'typescript',\n },\n experimental: {},\n },\n });\n return output.code;\n};\n\ncommander\n .name(name)\n .description(description)\n .version(version)\n .argument('<path>', 'glob pattern to find benchmarks')\n .addOption(new Option('-r, --report-types [reportTypes...]', 'statistic types to include in the report').choices(REPORT_TYPES).default(DEFAULT_REPORT_TYPES))\n .addOption(new Option('-w, --workers [workers]', 'number of concurent workers').default(DEFAULT_WORKERS).argParser(parseInt))\n .addOption(new Option('-f, --format [format]', 'output format').default('simple').choices(['simple', 'json', 'pjson', 'table']))\n .addOption(new Option('--abs-threshold [absThreshold]', 'absolute error threshold in nanoseconds').argParser(parseInt))\n .addOption(new Option('--rel-threshold [relThreshold]', 'relative error threshold (fraction between 0 and 1)').argParser(parseInt))\n .addOption(new Option('--warmup-cycles [warmupCycles]', 'number of warmup cycles before measuring').argParser(parseInt))\n .addOption(new Option('--max-cycles [maxCycles]', 'maximum measurement cycles per feed').argParser(parseInt))\n .addOption(new Option('--min-cycles [minCycles]', 'minimum measurement cycles per feed').argParser(parseInt))\n .action(async (path, executeOptions) => {\n const files = await glob(path, { absolute: true, cwd: process.cwd() }).catch(() => []);\n for (const file of files) {\n const stats = await stat(file).catch(() => false as const);\n if (stats && stats.isFile()) {\n const content = await readFile(file, 'utf8');\n const code = await transpile(content);\n let instance: Benchmark<unknown> | undefined;\n const benchmark = (...args: Parameters<(typeof Benchmark)['create']>) => {\n if (instance) {\n throw new Error('Only one benchmark per file is supported');\n }\n instance = Benchmark.create(...args);\n return instance;\n };\n const script = new SourceTextModule(code, {\n context: createContext({ benchmark }),\n });\n const imports = new Map();\n await script.link(async (specifier: string, referencingModule) => {\n if (imports.has(specifier)) {\n return imports.get(specifier);\n }\n const mod = await import(Module.isBuiltin(specifier) ? specifier : require.resolve(specifier));\n const exportNames = Object.keys(mod);\n const imported = new SyntheticModule(\n exportNames,\n () => {\n exportNames.forEach((key) => imported.setExport(key, mod[key]));\n },\n { identifier: specifier, context: referencingModule.context },\n );\n\n imports.set(specifier, imported);\n return imported;\n });\n await script.evaluate();\n\n if (instance) {\n const reports = await instance.execute(executeOptions);\n switch (executeOptions.format) {\n case 'json':\n {\n printJSONReports(reports);\n }\n break;\n case 'pjson':\n {\n printJSONReports(reports, 2);\n }\n break;\n case 'table':\n {\n printTableReports(reports);\n }\n break;\n default:\n printSimpleReports(reports);\n }\n }\n }\n }\n });\n\ncommander.parse(process.argv);\n"],"names":["createRequire","Module","SyntheticModule","createContext","SourceTextModule","stat","readFile","parse","print","Command","Option","glob","Benchmark","printTableReports","printJSONReports","printSimpleReports","DEFAULT_REPORT_TYPES","DEFAULT_WORKERS","REPORT_TYPES","require","url","name","description","version","commander","transpile","code","ast","syntax","dynamicImport","target","output","module","type","jsc","parser","experimental","argument","addOption","choices","default","argParser","parseInt","action","path","executeOptions","files","absolute","cwd","process","catch","file","stats","isFile","content","instance","benchmark","args","Error","create","script","context","imports","Map","link","specifier","referencingModule","has","get","mod","isBuiltin","resolve","exportNames","Object","keys","imported","forEach","key","setExport","identifier","set","evaluate","reports","execute","format","argv"],"mappings":"AAAA,SAASA,aAAa,EAAEC,MAAM,QAAQ,cAAc;AACpD,SAASC,eAAe,EAAEC,aAAa,EAAEC,gBAAgB,QAA4B,UAAU;AAC/F,SAASC,IAAI,EAAEC,QAAQ,QAAQ,mBAAmB;AAClD,SAASC,KAAK,EAAEC,KAAK,QAAQ,YAAY;AACzC,SAASC,OAAO,EAAEC,MAAM,QAAQ,YAAY;AAC5C,SAASC,IAAI,QAAQ,OAAO;AAC5B,SAASC,SAAS,EAAEC,iBAAiB,EAAEC,gBAAgB,EAAEC,kBAAkB,EAAEC,oBAAoB,EAAEC,eAAe,QAAQ,iBAAiB;AAC3I,SAASC,YAAY,QAAQ,aAAa;AAE1C,MAAMC,UAAUnB,cAAc,YAAYoB,GAAG;AAC7C,MAAM,EAAEC,IAAI,EAAEC,WAAW,EAAEC,OAAO,EAAE,GAAGJ,QAAQ;AAE/C,MAAMK,YAAY,IAAIf;AAEtB,MAAMgB,YAAY,OAAOC;IACvB,MAAMC,MAAM,MAAMpB,MAAMmB,MAAM;QAC5BE,QAAQ;QACRC,eAAe;QACfC,QAAQ;IACV;IAEA,MAAMC,SAAS,MAAMvB,MAAMmB,KAAK;QAC9BK,QAAQ;YACNC,MAAM;QACR;QACAC,KAAK;YACHJ,QAAQ;YACRK,QAAQ;gBACNP,QAAQ;YACV;YACAQ,cAAc,CAAC;QACjB;IACF;IACA,OAAOL,OAAOL,IAAI;AACpB;AAEAF,UACGH,IAAI,CAACA,MACLC,WAAW,CAACA,aACZC,OAAO,CAACA,SACRc,QAAQ,CAAC,UAAU,mCACnBC,SAAS,CAAC,IAAI5B,OAAO,uCAAuC,4CAA4C6B,OAAO,CAACrB,cAAcsB,OAAO,CAACxB,uBACtIsB,SAAS,CAAC,IAAI5B,OAAO,2BAA2B,+BAA+B8B,OAAO,CAACvB,iBAAiBwB,SAAS,CAACC,WAClHJ,SAAS,CAAC,IAAI5B,OAAO,yBAAyB,iBAAiB8B,OAAO,CAAC,UAAUD,OAAO,CAAC;IAAC;IAAU;IAAQ;IAAS;CAAQ,GAC7HD,SAAS,CAAC,IAAI5B,OAAO,kCAAkC,2CAA2C+B,SAAS,CAACC,WAC5GJ,SAAS,CAAC,IAAI5B,OAAO,kCAAkC,uDAAuD+B,SAAS,CAACC,WACxHJ,SAAS,CAAC,IAAI5B,OAAO,kCAAkC,4CAA4C+B,SAAS,CAACC,WAC7GJ,SAAS,CAAC,IAAI5B,OAAO,4BAA4B,uCAAuC+B,SAAS,CAACC,WAClGJ,SAAS,CAAC,IAAI5B,OAAO,4BAA4B,uCAAuC+B,SAAS,CAACC,WAClGC,MAAM,CAAC,OAAOC,MAAMC;IACnB,MAAMC,QAAQ,MAAMnC,KAAKiC,MAAM;QAAEG,UAAU;QAAMC,KAAKC,QAAQD,GAAG;IAAG,GAAGE,KAAK,CAAC,IAAM,EAAE;IACrF,KAAK,MAAMC,QAAQL,MAAO;QACxB,MAAMM,QAAQ,MAAM/C,KAAK8C,MAAMD,KAAK,CAAC,IAAM;QAC3C,IAAIE,SAASA,MAAMC,MAAM,IAAI;YAC3B,MAAMC,UAAU,MAAMhD,SAAS6C,MAAM;YACrC,MAAMzB,OAAO,MAAMD,UAAU6B;YAC7B,IAAIC;YACJ,MAAMC,YAAY,CAAC,GAAGC;gBACpB,IAAIF,UAAU;oBACZ,MAAM,IAAIG,MAAM;gBAClB;gBACAH,WAAW3C,UAAU+C,MAAM,IAAIF;gBAC/B,OAAOF;YACT;YACA,MAAMK,SAAS,IAAIxD,iBAAiBsB,MAAM;gBACxCmC,SAAS1D,cAAc;oBAAEqD;gBAAU;YACrC;YACA,MAAMM,UAAU,IAAIC;YACpB,MAAMH,OAAOI,IAAI,CAAC,OAAOC,WAAmBC;gBAC1C,IAAIJ,QAAQK,GAAG,CAACF,YAAY;oBAC1B,OAAOH,QAAQM,GAAG,CAACH;gBACrB;gBACA,MAAMI,MAAM,MAAM,MAAM,CAACpE,OAAOqE,SAAS,CAACL,aAAaA,YAAY9C,QAAQoD,OAAO,CAACN;gBACnF,MAAMO,cAAcC,OAAOC,IAAI,CAACL;gBAChC,MAAMM,WAAW,IAAIzE,gBACnBsE,aACA;oBACEA,YAAYI,OAAO,CAAC,CAACC,MAAQF,SAASG,SAAS,CAACD,KAAKR,GAAG,CAACQ,IAAI;gBAC/D,GACA;oBAAEE,YAAYd;oBAAWJ,SAASK,kBAAkBL,OAAO;gBAAC;gBAG9DC,QAAQkB,GAAG,CAACf,WAAWU;gBACvB,OAAOA;YACT;YACA,MAAMf,OAAOqB,QAAQ;YAErB,IAAI1B,UAAU;gBACZ,MAAM2B,UAAU,MAAM3B,SAAS4B,OAAO,CAACtC;gBACvC,OAAQA,eAAeuC,MAAM;oBAC3B,KAAK;wBACH;4BACEtE,iBAAiBoE;wBACnB;wBACA;oBACF,KAAK;wBACH;4BACEpE,iBAAiBoE,SAAS;wBAC5B;wBACA;oBACF,KAAK;wBACH;4BACErE,kBAAkBqE;wBACpB;wBACA;oBACF;wBACEnE,mBAAmBmE;gBACvB;YACF;QACF;IACF;AACF;AAEF1D,UAAUjB,KAAK,CAAC0C,QAAQoC,IAAI"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "createExecutor", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return createExecutor;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodeworker_threads = require("node:worker_threads");
|
|
12
|
+
const _nodeevents = require("node:events");
|
|
13
|
+
const _async = require("async");
|
|
14
|
+
const _typescjs = require("./types.cjs");
|
|
15
|
+
const _reportercjs = require("./reporter.cjs");
|
|
16
|
+
const _utilscjs = require("./utils.cjs");
|
|
17
|
+
const createExecutor = ({ workers, warmupCycles, maxCycles, minCycles, absThreshold, relThreshold, reportTypes })=>{
|
|
18
|
+
const executor = (0, _async.queue)(async ({ setup, teardown, pre, run, post, data })=>{
|
|
19
|
+
const setupCode = setup?.toString();
|
|
20
|
+
const teardownCode = teardown?.toString();
|
|
21
|
+
const preCode = pre?.toString();
|
|
22
|
+
const runCode = run.toString();
|
|
23
|
+
const postCode = post?.toString();
|
|
24
|
+
const controlSAB = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * _typescjs.CONTROL_SLOTS);
|
|
25
|
+
const durationsSAB = new SharedArrayBuffer(BigUint64Array.BYTES_PER_ELEMENT * maxCycles);
|
|
26
|
+
const workerFile = new URL('./worker.js', require("url").pathToFileURL(__filename).toString());
|
|
27
|
+
const workerData = {
|
|
28
|
+
setupCode,
|
|
29
|
+
teardownCode,
|
|
30
|
+
preCode,
|
|
31
|
+
runCode,
|
|
32
|
+
postCode,
|
|
33
|
+
data,
|
|
34
|
+
warmupCycles,
|
|
35
|
+
minCycles,
|
|
36
|
+
absThreshold,
|
|
37
|
+
relThreshold,
|
|
38
|
+
controlSAB,
|
|
39
|
+
durationsSAB
|
|
40
|
+
};
|
|
41
|
+
const worker = new _nodeworker_threads.Worker(workerFile, {
|
|
42
|
+
workerData
|
|
43
|
+
});
|
|
44
|
+
const [exitCode] = await (0, _nodeevents.once)(worker, 'exit');
|
|
45
|
+
if (exitCode !== 0) {
|
|
46
|
+
throw new Error(`worker exited with code ${exitCode}`);
|
|
47
|
+
}
|
|
48
|
+
const control = new Int32Array(controlSAB);
|
|
49
|
+
const count = control[_typescjs.Control.INDEX];
|
|
50
|
+
const durations = new BigUint64Array(durationsSAB).slice(0, count).sort(_utilscjs.cmp);
|
|
51
|
+
const report = reportTypes.map((type)=>[
|
|
52
|
+
type,
|
|
53
|
+
(0, _reportercjs.createReport)(durations, type)
|
|
54
|
+
]).concat([
|
|
55
|
+
[
|
|
56
|
+
'count',
|
|
57
|
+
count
|
|
58
|
+
]
|
|
59
|
+
]);
|
|
60
|
+
return Object.fromEntries(report);
|
|
61
|
+
}, workers);
|
|
62
|
+
executor.error((err)=>{
|
|
63
|
+
console.error(err);
|
|
64
|
+
});
|
|
65
|
+
return executor;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=executor.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/executor.ts"],"sourcesContent":["import { Worker } from 'node:worker_threads';\nimport { once } from 'node:events';\nimport { queue } from 'async';\nimport { RunOptions, ReportOptions, WorkerOptions, BenchmarkOptions, Control, ReportType, ReportTypeList, CONTROL_SLOTS } from './types.js';\nimport { createReport, Report } from './reporter.js';\nimport { cmp } from './utils.js';\n\nexport type ExecutorReport<R extends ReportTypeList> = Record<R[number], Report> & { count: number };\n\nexport interface ExecutorOptions<R extends ReportTypeList> extends BenchmarkOptions, ReportOptions<R> {\n workers?: number;\n maxCycles?: number;\n}\n\nexport const createExecutor = <TContext, TInput, R extends ReportTypeList>({\n workers,\n warmupCycles,\n maxCycles,\n minCycles,\n absThreshold,\n relThreshold,\n reportTypes,\n}: Required<ExecutorOptions<R>>) => {\n const executor = queue<RunOptions<TContext, TInput>>(async ({ setup, teardown, pre, run, post, data }) => {\n const setupCode = setup?.toString();\n const teardownCode = teardown?.toString();\n const preCode = pre?.toString();\n const runCode = run.toString()!;\n const postCode = post?.toString();\n\n const controlSAB = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * CONTROL_SLOTS);\n const durationsSAB = new SharedArrayBuffer(BigUint64Array.BYTES_PER_ELEMENT * maxCycles);\n\n const workerFile = new URL('./worker.js', import.meta.url);\n const workerData: WorkerOptions = {\n setupCode,\n teardownCode,\n preCode,\n runCode,\n postCode,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n\n controlSAB,\n durationsSAB,\n };\n\n const worker = new Worker(workerFile, {\n workerData,\n });\n const [exitCode] = await once(worker, 'exit');\n if (exitCode !== 0) {\n throw new Error(`worker exited with code ${exitCode}`);\n }\n\n const control = new Int32Array(controlSAB);\n const count = control[Control.INDEX];\n const durations = new BigUint64Array(durationsSAB).slice(0, count).sort(cmp);\n\n const report = reportTypes.map<[string, unknown]>((type) => [type, createReport(durations, type)] as [ReportType, Report]).concat([['count', count]]);\n return Object.fromEntries(report);\n }, workers);\n\n executor.error((err) => {\n console.error(err);\n });\n\n return executor;\n};\n"],"names":["createExecutor","workers","warmupCycles","maxCycles","minCycles","absThreshold","relThreshold","reportTypes","executor","queue","setup","teardown","pre","run","post","data","setupCode","toString","teardownCode","preCode","runCode","postCode","controlSAB","SharedArrayBuffer","Int32Array","BYTES_PER_ELEMENT","CONTROL_SLOTS","durationsSAB","BigUint64Array","workerFile","URL","workerData","worker","Worker","exitCode","once","Error","control","count","Control","INDEX","durations","slice","sort","cmp","report","map","type","createReport","concat","Object","fromEntries","error","err","console"],"mappings":";;;;+BAcaA;;;eAAAA;;;oCAdU;4BACF;uBACC;0BACyG;6BAC1F;0BACjB;AASb,MAAMA,iBAAiB,CAA6C,EACzEC,OAAO,EACPC,YAAY,EACZC,SAAS,EACTC,SAAS,EACTC,YAAY,EACZC,YAAY,EACZC,WAAW,EACkB;IAC7B,MAAMC,WAAWC,IAAAA,YAAK,EAA+B,OAAO,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAEC,IAAI,EAAE;QACnG,MAAMC,YAAYN,OAAOO;QACzB,MAAMC,eAAeP,UAAUM;QAC/B,MAAME,UAAUP,KAAKK;QACrB,MAAMG,UAAUP,IAAII,QAAQ;QAC5B,MAAMI,WAAWP,MAAMG;QAEvB,MAAMK,aAAa,IAAIC,kBAAkBC,WAAWC,iBAAiB,GAAGC,uBAAa;QACrF,MAAMC,eAAe,IAAIJ,kBAAkBK,eAAeH,iBAAiB,GAAGtB;QAE9E,MAAM0B,aAAa,IAAIC,IAAI,eAAe;QAC1C,MAAMC,aAA4B;YAChCf;YACAE;YACAC;YACAC;YACAC;YACAN;YAEAb;YACAE;YACAC;YACAC;YAEAgB;YACAK;QACF;QAEA,MAAMK,SAAS,IAAIC,0BAAM,CAACJ,YAAY;YACpCE;QACF;QACA,MAAM,CAACG,SAAS,GAAG,MAAMC,IAAAA,gBAAI,EAACH,QAAQ;QACtC,IAAIE,aAAa,GAAG;YAClB,MAAM,IAAIE,MAAM,CAAC,wBAAwB,EAAEF,UAAU;QACvD;QAEA,MAAMG,UAAU,IAAIb,WAAWF;QAC/B,MAAMgB,QAAQD,OAAO,CAACE,iBAAO,CAACC,KAAK,CAAC;QACpC,MAAMC,YAAY,IAAIb,eAAeD,cAAce,KAAK,CAAC,GAAGJ,OAAOK,IAAI,CAACC,aAAG;QAE3E,MAAMC,SAAStC,YAAYuC,GAAG,CAAoB,CAACC,OAAS;gBAACA;gBAAMC,IAAAA,yBAAY,EAACP,WAAWM;aAAM,EAA0BE,MAAM,CAAC;YAAC;gBAAC;gBAASX;aAAM;SAAC;QACpJ,OAAOY,OAAOC,WAAW,CAACN;IAC5B,GAAG5C;IAEHO,SAAS4C,KAAK,CAAC,CAACC;QACdC,QAAQF,KAAK,CAACC;IAChB;IAEA,OAAO7C;AACT"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RunOptions, ReportOptions, BenchmarkOptions, ReportTypeList } from './types.js';
|
|
2
|
+
import { Report } from './reporter.js';
|
|
3
|
+
export type ExecutorReport<R extends ReportTypeList> = Record<R[number], Report> & {
|
|
4
|
+
count: number;
|
|
5
|
+
};
|
|
6
|
+
export interface ExecutorOptions<R extends ReportTypeList> extends BenchmarkOptions, ReportOptions<R> {
|
|
7
|
+
workers?: number;
|
|
8
|
+
maxCycles?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const createExecutor: <TContext, TInput, R extends ReportTypeList>({ workers, warmupCycles, maxCycles, minCycles, absThreshold, relThreshold, reportTypes, }: Required<ExecutorOptions<R>>) => import("async").QueueObject<RunOptions<TContext, TInput>>;
|