@nestia/benchmark 14.0.1 → 14.0.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/lib/DynamicBenchmarker.d.ts +235 -6
- package/lib/DynamicBenchmarker.js +212 -61
- package/lib/DynamicBenchmarker.js.map +1 -1
- package/lib/IBenchmarkEvent.d.ts +19 -0
- package/lib/internal/DynamicBenchmarkReporter.d.ts +50 -1
- package/lib/internal/DynamicBenchmarkReporter.js +30 -11
- package/lib/internal/DynamicBenchmarkReporter.js.map +1 -1
- package/lib/internal/DynamicBenchmarkStatistics.d.ts +25 -0
- package/lib/internal/DynamicBenchmarkStatistics.js +51 -0
- package/lib/internal/DynamicBenchmarkStatistics.js.map +1 -0
- package/lib/internal/IBenchmarkMaster.d.ts +26 -0
- package/lib/internal/IBenchmarkServant.d.ts +19 -0
- package/package.json +4 -3
- package/src/DynamicBenchmarker.ts +376 -95
- package/src/IBenchmarkEvent.ts +24 -0
- package/src/internal/DynamicBenchmarkReporter.ts +59 -8
- package/src/internal/DynamicBenchmarkStatistics.ts +62 -0
- package/src/internal/IBenchmarkMaster.ts +27 -0
- package/src/internal/IBenchmarkServant.ts +19 -0
|
@@ -47,9 +47,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
48
|
exports.DynamicBenchmarker = void 0;
|
|
49
49
|
const fs_1 = __importDefault(require("fs"));
|
|
50
|
+
const os_1 = __importDefault(require("os"));
|
|
51
|
+
const path_1 = __importDefault(require("path"));
|
|
50
52
|
const tgrid_1 = require("tgrid");
|
|
51
53
|
const tstl_1 = require("tstl");
|
|
52
54
|
const DynamicBenchmarkReporter_1 = require("./internal/DynamicBenchmarkReporter");
|
|
55
|
+
const DynamicBenchmarkStatistics_1 = require("./internal/DynamicBenchmarkStatistics");
|
|
53
56
|
/**
|
|
54
57
|
* Dynamic benchmark executor running prefixed functions.
|
|
55
58
|
*
|
|
@@ -75,12 +78,46 @@ const DynamicBenchmarkReporter_1 = require("./internal/DynamicBenchmarkReporter"
|
|
|
75
78
|
* Additionally, if you hope to see some utilization cases, see the below
|
|
76
79
|
* example tagged links.
|
|
77
80
|
*
|
|
81
|
+
* Processing cost: Totals are split across T servants once; E events are
|
|
82
|
+
* aggregated with hash-based endpoint grouping. Progress notifications update
|
|
83
|
+
* the aggregate from one servant counter delta in constant time. Event
|
|
84
|
+
* statistics and rendering traverse their input populations; discovery visits
|
|
85
|
+
* each real directory once.
|
|
86
|
+
*
|
|
87
|
+
* Computation reuse: A master distributes distinct request budgets rather than
|
|
88
|
+
* replaying one effectful request. Endpoint grouping shares one event
|
|
89
|
+
* population across whole-run and endpoint statistics. Results are not cached
|
|
90
|
+
* across benchmark runs because server state and timing change.
|
|
91
|
+
*
|
|
92
|
+
* Resource ownership: Each master owns at most threads connectors and
|
|
93
|
+
* simultaneous function workers; connector closure is attempted on
|
|
94
|
+
* connection/execution success or failure; a rejected close is suppressed and
|
|
95
|
+
* may leave an unreleased child process. Events retained by servants/master
|
|
96
|
+
* scale with logged events, and memory samples with run duration. The
|
|
97
|
+
* independent sampler detaches its report target on stop or rejection and
|
|
98
|
+
* clears/wakes its owned timer. A pending caller memory getter has no
|
|
99
|
+
* cancellation hook, but its task retains only the sampler state/getter and
|
|
100
|
+
* cannot keep the master report arrays, connectors or event collections through
|
|
101
|
+
* that state. Its eventual result is discarded after deactivation. Returned
|
|
102
|
+
* reports transfer their arrays to callers.
|
|
103
|
+
*
|
|
104
|
+
* Platform boundary: WorkerConnector process mode owns Node child-process
|
|
105
|
+
* launch/IPC and its explicit stdio modes. Feature discovery resolves the
|
|
106
|
+
* caller location with native path and fs realpath/stat, follows directory
|
|
107
|
+
* links with realpath cycle detection and imports discovered native absolute
|
|
108
|
+
* paths. It does not infer filesystem case policy from OS names.
|
|
109
|
+
*
|
|
78
110
|
* @author Jeongho Nam - https://github.com/samchon
|
|
79
111
|
* @example
|
|
80
112
|
* https://github.com/samchon/nestia-start/blob/master/test/benchmaark/index.ts
|
|
81
113
|
*
|
|
82
114
|
* @example
|
|
83
115
|
* https://github.com/samchon/backend/blob/master/test/benchmark/index.ts
|
|
116
|
+
*
|
|
117
|
+
* @evidence contracts/common.md#principled-implementation The master spawns one child process per thread through tgrid's process-mode `WorkerConnector`, drives each servant over RPC, and merges the returned events; totals are split by floor plus remainder so the shares sum to the requested count and simultaneous budget.
|
|
118
|
+
* @evidence contracts/common.md#clear-and-simple-design One namespace is the public surface (master, servant, markdown, props, report); execution, discovery, and cleanup helpers stay private, and statistics and rendering live in their own internal namespaces.
|
|
119
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Nothing names a server, feature, or file: the feature extension, prefix, and filter are caller inputs, and the servant path is a property rather than an assumed location.
|
|
120
|
+
* @evidence contracts/common.md#meaningful-documentation The namespace prose explains the two-program model, what each program does, and how to obtain markdown, with links to the member documentation and to example repositories.
|
|
84
121
|
*/
|
|
85
122
|
var DynamicBenchmarker;
|
|
86
123
|
(function (DynamicBenchmarker) {
|
|
@@ -92,11 +129,48 @@ var DynamicBenchmarker;
|
|
|
92
129
|
* Note that, {@link IMasterProps.servant} property must be the path of the
|
|
93
130
|
* servant program executing the {@link servant} function.
|
|
94
131
|
*
|
|
132
|
+
* The servants are child processes. When a servant fails to connect or to
|
|
133
|
+
* execute, every servant receives a close attempt before the returned promise
|
|
134
|
+
* rejects.
|
|
135
|
+
*
|
|
136
|
+
* Processing cost: Totals are split across T servants once; E events are
|
|
137
|
+
* aggregated with hash-based endpoint grouping. Progress notifications update
|
|
138
|
+
* the aggregate from one servant counter delta in constant time. Event
|
|
139
|
+
* statistics and rendering traverse their input populations; discovery visits
|
|
140
|
+
* each real directory once.
|
|
141
|
+
*
|
|
142
|
+
* Computation reuse: A master distributes distinct request budgets rather
|
|
143
|
+
* than replaying one effectful request. Endpoint grouping shares one event
|
|
144
|
+
* population across whole-run and endpoint statistics. Results are not cached
|
|
145
|
+
* across benchmark runs because server state and timing change.
|
|
146
|
+
*
|
|
147
|
+
* Resource ownership: Each master owns at most threads connectors and
|
|
148
|
+
* simultaneous function workers; connector closure is attempted on
|
|
149
|
+
* connection/execution success or failure; a rejected close is suppressed and
|
|
150
|
+
* may leave an unreleased child process. Events retained by servants/master
|
|
151
|
+
* scale with logged events, and memory samples with run duration. The
|
|
152
|
+
* independent sampler detaches its report target on stop or rejection and
|
|
153
|
+
* clears/wakes its owned timer. A pending caller memory getter has no
|
|
154
|
+
* cancellation hook, but its task retains only the sampler state/getter and
|
|
155
|
+
* cannot keep the master report arrays, connectors or event collections
|
|
156
|
+
* through that state. Its eventual result is discarded after deactivation.
|
|
157
|
+
* Returned reports transfer their arrays to callers.
|
|
158
|
+
*
|
|
159
|
+
* Platform boundary: WorkerConnector process mode owns Node child-process
|
|
160
|
+
* launch/IPC and its explicit stdio modes. Feature discovery resolves the
|
|
161
|
+
* caller location with native path and fs realpath/stat, follows directory
|
|
162
|
+
* links with realpath cycle detection and imports discovered native absolute
|
|
163
|
+
* paths. It does not infer filesystem case policy from OS names.
|
|
164
|
+
*
|
|
95
165
|
* @param props Properties of the master program
|
|
96
166
|
* @returns Benchmark report
|
|
167
|
+
* @evidence contracts/common.md#principled-implementation Inputs are validated as safe integers before any process starts; totals are distributed by floor plus remainder; servants execute concurrently and every event is grouped by method and path template in a hash map; closing is attempted for every spawned servant on success and on failure, and the memory sampler is deactivated when the run ends, detaching its report array and clearing/waking its owned timer immediately; a pending caller getter may settle later but cannot append.
|
|
168
|
+
* @evidence contracts/common.md#clear-and-simple-design One function owns the run and keeps the sequence readable: validate, spawn, sample, execute, close, aggregate; statistics come from `DynamicBenchmarkStatistics` and the closing helper is shared by the failure and success paths.
|
|
169
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts A servant that fails to close cannot alter a finished report and is not allowed to hide the run's own error, so closing failures are dropped on purpose; no other error is swallowed except a rejecting memory getter, which ends sampling as documented.
|
|
170
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the master does, that the servant property must name the servant program, that servants are child processes, and that every servant receives a close attempt before a failure rejects.
|
|
97
171
|
*/
|
|
98
172
|
DynamicBenchmarker.master = (props) => __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
var _a;
|
|
173
|
+
var _a, _b;
|
|
100
174
|
if (!Number.isSafeInteger(props.count) || props.count < 0)
|
|
101
175
|
throw new Error("DynamicBenchmarker.master(): count must be a non-negative integer.");
|
|
102
176
|
if (!Number.isSafeInteger(props.threads) || props.threads <= 0)
|
|
@@ -106,6 +180,7 @@ var DynamicBenchmarker;
|
|
|
106
180
|
if (props.simultaneous < props.threads)
|
|
107
181
|
throw new Error(`DynamicBenchmarker.master(): simultaneous (${props.simultaneous}) must not be less than threads (${props.threads}), as each servant runs at least one request at a time.`);
|
|
108
182
|
const completes = new Array(props.threads).fill(0);
|
|
183
|
+
let completed = 0;
|
|
109
184
|
// the first `total % threads` servants take one more than the rest, so the
|
|
110
185
|
// shares sum to the total
|
|
111
186
|
const distribute = (total) => new Array(props.threads)
|
|
@@ -114,39 +189,46 @@ var DynamicBenchmarker;
|
|
|
114
189
|
(index < total % props.threads ? 1 : 0));
|
|
115
190
|
const counts = distribute(props.count);
|
|
116
191
|
const budgets = distribute(props.simultaneous);
|
|
117
|
-
|
|
192
|
+
// every servant is a child process, so each connector created must be
|
|
193
|
+
// closed on every path out of this function, including a failed connection
|
|
194
|
+
// of a sibling
|
|
195
|
+
const spawned = [];
|
|
196
|
+
const settled = yield Promise.allSettled(new Array(props.threads).fill(null).map((_, i) => __awaiter(this, void 0, void 0, function* () {
|
|
118
197
|
var _a;
|
|
119
198
|
const connector = new tgrid_1.WorkerConnector(null, {
|
|
120
199
|
filter: (_a = props.filter) !== null && _a !== void 0 ? _a : (() => true),
|
|
121
200
|
progress: (current) => {
|
|
201
|
+
completed += current - completes[i];
|
|
122
202
|
completes[i] = current;
|
|
123
203
|
if (props.progress)
|
|
124
|
-
props.progress(
|
|
204
|
+
props.progress(completed);
|
|
125
205
|
},
|
|
126
206
|
}, "process");
|
|
207
|
+
spawned.push(connector);
|
|
127
208
|
yield connector.connect(props.servant, { stdio: props.stdio });
|
|
128
|
-
return connector;
|
|
129
209
|
})));
|
|
210
|
+
const refused = settled.find((result) => result.status === "rejected");
|
|
211
|
+
if (refused !== undefined) {
|
|
212
|
+
yield closeAll(spawned);
|
|
213
|
+
throw refused.reason;
|
|
214
|
+
}
|
|
215
|
+
const servants = spawned;
|
|
130
216
|
const started_at = new Date();
|
|
131
217
|
const memories = [];
|
|
132
|
-
let completed_at
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
simultaneous: budgets[index],
|
|
147
|
-
})))).flat();
|
|
148
|
-
completed_at = new Date();
|
|
149
|
-
yield Promise.all(servants.map((connector) => connector.close()));
|
|
218
|
+
let completed_at;
|
|
219
|
+
let events;
|
|
220
|
+
const stopSampling = startMemorySampler((_a = props.memory) !== null && _a !== void 0 ? _a : (() => __awaiter(this, void 0, void 0, function* () { return process.memoryUsage(); })), memories);
|
|
221
|
+
try {
|
|
222
|
+
events = (yield Promise.all(servants.map((connector, index) => connector.getDriver().execute({
|
|
223
|
+
count: counts[index],
|
|
224
|
+
simultaneous: budgets[index],
|
|
225
|
+
})))).flat();
|
|
226
|
+
completed_at = new Date();
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
stopSampling();
|
|
230
|
+
yield closeAll(servants);
|
|
231
|
+
}
|
|
150
232
|
if (props.progress)
|
|
151
233
|
props.progress(props.count);
|
|
152
234
|
const endpoints = new tstl_1.HashMap((key) => (0, tstl_1.hash)(key.method, key.path), (x, y) => x.method === y.method && x.path === y.path);
|
|
@@ -154,15 +236,15 @@ var DynamicBenchmarker;
|
|
|
154
236
|
endpoints
|
|
155
237
|
.take({
|
|
156
238
|
method: e.metadata.method,
|
|
157
|
-
path: (
|
|
239
|
+
path: (_b = e.metadata.template) !== null && _b !== void 0 ? _b : e.metadata.path,
|
|
158
240
|
}, () => [])
|
|
159
241
|
.push(e);
|
|
160
242
|
return {
|
|
161
243
|
count: props.count,
|
|
162
244
|
threads: props.threads,
|
|
163
245
|
simultaneous: props.simultaneous,
|
|
164
|
-
statistics:
|
|
165
|
-
endpoints: [...endpoints].map((it) => (Object.assign(Object.assign({},
|
|
246
|
+
statistics: DynamicBenchmarkStatistics_1.DynamicBenchmarkStatistics.of(events),
|
|
247
|
+
endpoints: [...endpoints].map((it) => (Object.assign(Object.assign({}, DynamicBenchmarkStatistics_1.DynamicBenchmarkStatistics.of(it.second)), it.first))),
|
|
166
248
|
started_at: started_at.toISOString(),
|
|
167
249
|
completed_at: completed_at.toISOString(),
|
|
168
250
|
memories,
|
|
@@ -173,8 +255,33 @@ var DynamicBenchmarker;
|
|
|
173
255
|
*
|
|
174
256
|
* Creates a servant program executing the prefixed functions in parallel.
|
|
175
257
|
*
|
|
258
|
+
* Processing cost: Each execute request discovers matching modules once, then
|
|
259
|
+
* runs at most simultaneous loop workers and count invocations. Event storage
|
|
260
|
+
* grows with actual logger calls rather than an assumed one event per
|
|
261
|
+
* invocation.
|
|
262
|
+
*
|
|
263
|
+
* Computation reuse: Discovery is refreshed for each execute request because
|
|
264
|
+
* the supplied filter and filesystem can change; requests themselves are
|
|
265
|
+
* effectful and cannot reuse earlier observations.
|
|
266
|
+
*
|
|
267
|
+
* Resource ownership: The returned WorkerServer transfers connection
|
|
268
|
+
* lifecycle to its caller. Each execute owns its discovery collections,
|
|
269
|
+
* workers and event arrays until it completes; the master closes its servant
|
|
270
|
+
* process. No discovered-module cache is retained by this namespace beyond
|
|
271
|
+
* Node own loader.
|
|
272
|
+
*
|
|
273
|
+
* Platform boundary: WorkerConnector process mode owns Node child-process
|
|
274
|
+
* launch/IPC and its explicit stdio modes. Feature discovery resolves the
|
|
275
|
+
* caller location with native path and fs realpath/stat, follows directory
|
|
276
|
+
* links with realpath cycle detection and imports discovered native absolute
|
|
277
|
+
* paths. It does not infer filesystem case policy from OS names.
|
|
278
|
+
*
|
|
176
279
|
* @param props Properties of the servant program
|
|
177
280
|
* @returns Servant program as a worker server
|
|
281
|
+
* @evidence contracts/common.md#principled-implementation A servant opens a `WorkerServer` that exposes one `execute` operation; the master decides counts and budgets, so the servant only needs the location and naming rules to find functions.
|
|
282
|
+
* @evidence contracts/common.md#clear-and-simple-design A thin adapter over the worker server whose behavior lives in the private `execute` and `iterate` helpers.
|
|
283
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Discovery is driven by the caller's location, extension, and prefix, and by the master's filter; no file or function name is assumed.
|
|
284
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states that it creates the servant program and returns it as a worker server.
|
|
178
285
|
*/
|
|
179
286
|
DynamicBenchmarker.servant = (props) => __awaiter(this, void 0, void 0, function* () {
|
|
180
287
|
const server = new tgrid_1.WorkerServer();
|
|
@@ -189,19 +296,36 @@ var DynamicBenchmarker;
|
|
|
189
296
|
/**
|
|
190
297
|
* Convert the benchmark report to markdown content.
|
|
191
298
|
*
|
|
299
|
+
* Processing cost: Rendering delegates to the reporter and scales with report
|
|
300
|
+
* endpoints, samples and output bytes; host metadata is obtained through Node
|
|
301
|
+
* os APIs.
|
|
302
|
+
*
|
|
303
|
+
* Platform boundary: The wrapper obtains host information through Node os
|
|
304
|
+
* APIs and passes those facts to the pure renderer without constructing
|
|
305
|
+
* native file paths or shell commands.
|
|
306
|
+
*
|
|
192
307
|
* @param report Benchmark report
|
|
193
308
|
* @returns Markdown content
|
|
309
|
+
* @evidence contracts/common.md#principled-implementation Rendering is a pure function of the report and a few host facts, delegated to the reporter so the report type and its presentation stay separate.
|
|
310
|
+
* @evidence contracts/common.md#clear-and-simple-design The wrapper captures three native host facts and delegates rendering, giving users one entry point without exposing the internal reporter.
|
|
311
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The function observes native host facts and formats the report without altering its measurements.
|
|
312
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states input and output: a report in, markdown content out.
|
|
194
313
|
*/
|
|
195
|
-
DynamicBenchmarker.markdown = (report) => DynamicBenchmarkReporter_1.DynamicBenchmarkReporter.markdown(report
|
|
314
|
+
DynamicBenchmarker.markdown = (report) => { var _a; return DynamicBenchmarkReporter_1.DynamicBenchmarkReporter.markdown(report, {
|
|
315
|
+
cpu: (_a = os_1.default.cpus()[0]) === null || _a === void 0 ? void 0 : _a.model,
|
|
316
|
+
memory: os_1.default.totalmem(),
|
|
317
|
+
node: process.version,
|
|
318
|
+
}); };
|
|
196
319
|
const execute = (ctx) => (mass) => __awaiter(this, void 0, void 0, function* () {
|
|
197
320
|
const functions = [];
|
|
198
321
|
yield iterate({
|
|
199
322
|
collection: functions,
|
|
200
323
|
driver: ctx.driver,
|
|
201
324
|
props: ctx.props,
|
|
202
|
-
})(ctx.props.location);
|
|
325
|
+
})(path_1.default.resolve(ctx.props.location));
|
|
203
326
|
const entireEvents = [];
|
|
204
327
|
let scheduled = 0;
|
|
328
|
+
let completed = 0;
|
|
205
329
|
yield Promise.all(new Array(mass.simultaneous)
|
|
206
330
|
.fill(null)
|
|
207
331
|
.map(() => 1)
|
|
@@ -231,29 +355,84 @@ var DynamicBenchmarker;
|
|
|
231
355
|
for (const e of localEvents)
|
|
232
356
|
e.success = false;
|
|
233
357
|
}
|
|
234
|
-
|
|
235
|
-
ctx.driver.progress(entireEvents.length).catch(() => { });
|
|
358
|
+
ctx.driver.progress(++completed).catch(() => { });
|
|
236
359
|
}
|
|
237
360
|
})));
|
|
238
|
-
yield ctx.driver.progress(
|
|
361
|
+
yield ctx.driver.progress(completed);
|
|
239
362
|
return entireEvents;
|
|
240
363
|
});
|
|
241
364
|
})(DynamicBenchmarker || (exports.DynamicBenchmarker = DynamicBenchmarker = {}));
|
|
242
|
-
|
|
365
|
+
/**
|
|
366
|
+
* Keeps the sampler's pending caller task separate from the master's report,
|
|
367
|
+
* connectors and events. Stopping detaches the report array immediately;
|
|
368
|
+
* cancellation of a caller-owned getter remains its caller's responsibility.
|
|
369
|
+
*/
|
|
370
|
+
const startMemorySampler = (getter, memories) => {
|
|
371
|
+
const state = {
|
|
372
|
+
active: true,
|
|
373
|
+
target: memories,
|
|
374
|
+
};
|
|
375
|
+
sampleMemory(getter, state).catch(() => { });
|
|
376
|
+
return () => stopMemorySampler(state);
|
|
377
|
+
};
|
|
378
|
+
const stopMemorySampler = (state) => {
|
|
379
|
+
state.active = false;
|
|
380
|
+
state.target = null;
|
|
381
|
+
if (state.timer !== undefined)
|
|
382
|
+
clearTimeout(state.timer);
|
|
383
|
+
state.timer = undefined;
|
|
384
|
+
const wake = state.wake;
|
|
385
|
+
state.wake = undefined;
|
|
386
|
+
wake === null || wake === void 0 ? void 0 : wake();
|
|
387
|
+
};
|
|
388
|
+
const sampleMemory = (getter, state) => __awaiter(void 0, void 0, void 0, function* () {
|
|
389
|
+
try {
|
|
390
|
+
while (state.active) {
|
|
391
|
+
yield new Promise((resolve) => {
|
|
392
|
+
state.wake = resolve;
|
|
393
|
+
state.timer = setTimeout(() => {
|
|
394
|
+
state.timer = undefined;
|
|
395
|
+
state.wake = undefined;
|
|
396
|
+
resolve();
|
|
397
|
+
}, 1000);
|
|
398
|
+
});
|
|
399
|
+
if (!state.active)
|
|
400
|
+
return;
|
|
401
|
+
const usage = yield getter();
|
|
402
|
+
if (!state.active)
|
|
403
|
+
return;
|
|
404
|
+
state.target.push({ usage, time: new Date().toISOString() });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
finally {
|
|
408
|
+
stopMemorySampler(state);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
// A servant that fails to close cannot change a finished report, and must not
|
|
412
|
+
// hide the error that ended the run, so a failed close is dropped.
|
|
413
|
+
const closeAll = (servants) => __awaiter(void 0, void 0, void 0, function* () {
|
|
414
|
+
yield Promise.allSettled(servants.map((connector) => connector.close()));
|
|
415
|
+
});
|
|
416
|
+
const iterate = (ctx) => (path_2, ...args_1) => __awaiter(void 0, [path_2, ...args_1], void 0, function* (path, visited = new Set()) {
|
|
243
417
|
var _a;
|
|
418
|
+
const identity = yield fs_1.default.promises.realpath(path);
|
|
419
|
+
if (visited.has(identity))
|
|
420
|
+
return;
|
|
421
|
+
visited.add(identity);
|
|
244
422
|
const directory = yield fs_1.default.promises.readdir(path);
|
|
245
423
|
for (const file of directory) {
|
|
246
424
|
const location = `${path}/${file}`;
|
|
247
425
|
const stat = yield fs_1.default.promises.stat(location);
|
|
248
426
|
if (stat.isDirectory() === true)
|
|
249
|
-
yield iterate(ctx)(location);
|
|
427
|
+
yield iterate(ctx)(location, visited);
|
|
250
428
|
// Load feature files whose extension matches `props.extension`. This is
|
|
251
429
|
// configurable instead of inferred from the servant's own module
|
|
252
430
|
// extension, because the benchmark library may be built (`.js`) while the
|
|
253
431
|
// feature files it drives are run from source (`.ts`, e.g. under `ttsx`);
|
|
254
432
|
// inferring would look for `.js` features that do not exist, load
|
|
255
433
|
// nothing, and spin forever.
|
|
256
|
-
else if (
|
|
434
|
+
else if (stat.isFile() &&
|
|
435
|
+
file.endsWith(`.${(_a = ctx.props.extension) !== null && _a !== void 0 ? _a : "js"}`) &&
|
|
257
436
|
file.endsWith(".d.ts") === false) {
|
|
258
437
|
// GATE BY FILE NAME (PREFIX & FILTER), SO THAT EXCLUDED FILES ARE
|
|
259
438
|
// NEVER IMPORTED.
|
|
@@ -275,32 +454,4 @@ const iterate = (ctx) => (path) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
275
454
|
}
|
|
276
455
|
}
|
|
277
456
|
});
|
|
278
|
-
const statistics = (events) => {
|
|
279
|
-
const successes = events.filter((event) => event.success);
|
|
280
|
-
return Object.assign({ count: events.length, success: successes.length }, average(events));
|
|
281
|
-
};
|
|
282
|
-
const average = (events) => {
|
|
283
|
-
if (events.length === 0)
|
|
284
|
-
return {
|
|
285
|
-
mean: null,
|
|
286
|
-
stdev: null,
|
|
287
|
-
minimum: null,
|
|
288
|
-
maximum: null,
|
|
289
|
-
};
|
|
290
|
-
let mean = 0;
|
|
291
|
-
let stdev = 0;
|
|
292
|
-
let minimum = Number.MAX_SAFE_INTEGER;
|
|
293
|
-
let maximum = Number.MIN_SAFE_INTEGER;
|
|
294
|
-
for (const event of events) {
|
|
295
|
-
const elapsed = new Date(event.completed_at).getTime() -
|
|
296
|
-
new Date(event.started_at).getTime();
|
|
297
|
-
mean += elapsed;
|
|
298
|
-
stdev += elapsed * elapsed;
|
|
299
|
-
minimum = Math.min(minimum, elapsed);
|
|
300
|
-
maximum = Math.max(maximum, elapsed);
|
|
301
|
-
}
|
|
302
|
-
mean /= events.length;
|
|
303
|
-
stdev = Math.sqrt(stdev / events.length - mean * mean);
|
|
304
|
-
return { mean, stdev, minimum, maximum };
|
|
305
|
-
};
|
|
306
457
|
//# sourceMappingURL=DynamicBenchmarker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DynamicBenchmarker.js","sourceRoot":"","sources":["../src/DynamicBenchmarker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAAoB;AACpB,iCAA8D;AAC9D,+
|
|
1
|
+
{"version":3,"file":"DynamicBenchmarker.js","sourceRoot":"","sources":["../src/DynamicBenchmarker.ts"],"names":[],"mappings":"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"}
|
package/lib/IBenchmarkEvent.d.ts
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
import { IFetchRoute } from "@nestia/fetcher";
|
|
2
|
+
/**
|
|
3
|
+
* One benchmarked request as the servant observed it.
|
|
4
|
+
*
|
|
5
|
+
* `metadata` is the fetch route, `status` is the HTTP status or `null` when
|
|
6
|
+
* there was no response, and the three timestamps are ISO 8601 strings, with
|
|
7
|
+
* `respond_at` `null` when no response arrived. `success` is `false` for every
|
|
8
|
+
* request made by a benchmark function that threw.
|
|
9
|
+
*
|
|
10
|
+
* @evidence contracts/common.md#principled-implementation The event mirrors the fetcher's log event with timestamps in ISO strings, so it can cross the process boundary as plain data.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record shared by the servant, the master, and the report code.
|
|
12
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Route, status and times come from the fetcher's event; success records whether the enclosing benchmark function threw, independent of HTTP status.
|
|
13
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states each optional state and the meaning of success.
|
|
14
|
+
*/
|
|
2
15
|
export interface IBenchmarkEvent {
|
|
16
|
+
/** Fetch route, including its concrete path and optional grouping template. */
|
|
3
17
|
metadata: IFetchRoute<any>;
|
|
18
|
+
/** HTTP status, or null when the request received no response. */
|
|
4
19
|
status: number | null;
|
|
20
|
+
/** ISO 8601 time when the request started. */
|
|
5
21
|
started_at: string;
|
|
22
|
+
/** ISO 8601 response time, or null when no response arrived. */
|
|
6
23
|
respond_at: string | null;
|
|
24
|
+
/** ISO 8601 time when the request completed or failed. */
|
|
7
25
|
completed_at: string;
|
|
26
|
+
/** Whether the enclosing benchmark function completed without throwing. */
|
|
8
27
|
success: boolean;
|
|
9
28
|
}
|
|
@@ -1,4 +1,53 @@
|
|
|
1
1
|
import { DynamicBenchmarker } from "../DynamicBenchmarker";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a benchmark report as markdown.
|
|
4
|
+
*
|
|
5
|
+
* @evidence contracts/common.md#principled-implementation The reporter formats one report into fixed sections (specifications, arguments, time, statistics, memory chart, endpoints, failures) using a fixed locale.
|
|
6
|
+
* @evidence contracts/common.md#clear-and-simple-design A one-function namespace, internal to the package, that keeps presentation out of the benchmark logic.
|
|
7
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The content is computed from the report and host facts; no numbers are hardcoded.
|
|
8
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its single job.
|
|
9
|
+
*/
|
|
2
10
|
export declare namespace DynamicBenchmarkReporter {
|
|
3
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Host facts captured by the caller when a report is rendered.
|
|
13
|
+
*
|
|
14
|
+
* An absent CPU model means the platform exposed no CPU information. Memory
|
|
15
|
+
* remains in bytes until rendering, and the Node version is displayed
|
|
16
|
+
* verbatim.
|
|
17
|
+
*
|
|
18
|
+
* Platform boundary: Missing CPU data is represented explicitly rather than
|
|
19
|
+
* inferred from an operating-system name; memory and version retain Node's
|
|
20
|
+
* native units and spelling.
|
|
21
|
+
*
|
|
22
|
+
* @evidence contracts/common.md#principled-implementation CPU absence, memory bytes and the runtime version represent the three facts displayed by the renderer without depending on a platform-specific provider.
|
|
23
|
+
* @evidence contracts/common.md#clear-and-simple-design One record separates host observation from report formatting; each member supplies one displayed fact.
|
|
24
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The record describes native facts supplied by the actual public caller and introduces no fixture-specific behavior.
|
|
25
|
+
* @evidence contracts/common.md#meaningful-documentation Member comments explain absence, units and display semantics.
|
|
26
|
+
*/
|
|
27
|
+
interface IHost {
|
|
28
|
+
/** First CPU model, or undefined when the platform reports no CPU. */
|
|
29
|
+
cpu: string | undefined;
|
|
30
|
+
/** Total host memory in bytes. */
|
|
31
|
+
memory: number;
|
|
32
|
+
/** Node runtime version as reported by process.version. */
|
|
33
|
+
node: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Renders the report as markdown.
|
|
37
|
+
*
|
|
38
|
+
* Numbers use the fixed `en-US` locale, so a report reads the same on every
|
|
39
|
+
* machine. Decimals are truncated, not rounded, to two places. The CPU model
|
|
40
|
+
* is `unknown` when the platform exposes no CPU information.
|
|
41
|
+
*
|
|
42
|
+
* Processing cost: Endpoint and failure ordering require comparison sorts,
|
|
43
|
+
* costing O(E log E); four memory series each scan M samples, and temporary
|
|
44
|
+
* rows and final text scale with displayed data. Sorting copies preserve the
|
|
45
|
+
* caller's endpoint order.
|
|
46
|
+
*
|
|
47
|
+
* @evidence contracts/common.md#principled-implementation Each table row is built from the same statistics record; `Math.trunc` on the value scaled by 100 truncates toward zero to two decimals, including negative elapsed values after a wall-clock adjustment. `en-US` fixes separators, and an absent CPU model is displayed as `unknown`.
|
|
48
|
+
* @evidence contracts/common.md#clear-and-simple-design Small local helpers (`integer`, `format`, `row`, `line`) share the formatting rules inside one function, so one place decides how a number reads.
|
|
49
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The report states only the report's measurements and supplied host facts; nothing describes an unmeasured backend server or changes foreign runtime methods.
|
|
50
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the locale, the truncation, and the CPU fallback.
|
|
51
|
+
*/
|
|
52
|
+
const markdown: (report: DynamicBenchmarker.IReport, host: IHost) => string;
|
|
4
53
|
}
|
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.DynamicBenchmarkReporter = void 0;
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Renders a benchmark report as markdown.
|
|
6
|
+
*
|
|
7
|
+
* @evidence contracts/common.md#principled-implementation The reporter formats one report into fixed sections (specifications, arguments, time, statistics, memory chart, endpoints, failures) using a fixed locale.
|
|
8
|
+
* @evidence contracts/common.md#clear-and-simple-design A one-function namespace, internal to the package, that keeps presentation out of the benchmark logic.
|
|
9
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The content is computed from the report and host facts; no numbers are hardcoded.
|
|
10
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its single job.
|
|
11
|
+
*/
|
|
8
12
|
var DynamicBenchmarkReporter;
|
|
9
13
|
(function (DynamicBenchmarkReporter) {
|
|
10
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Renders the report as markdown.
|
|
16
|
+
*
|
|
17
|
+
* Numbers use the fixed `en-US` locale, so a report reads the same on every
|
|
18
|
+
* machine. Decimals are truncated, not rounded, to two places. The CPU model
|
|
19
|
+
* is `unknown` when the platform exposes no CPU information.
|
|
20
|
+
*
|
|
21
|
+
* Processing cost: Endpoint and failure ordering require comparison sorts,
|
|
22
|
+
* costing O(E log E); four memory series each scan M samples, and temporary
|
|
23
|
+
* rows and final text scale with displayed data. Sorting copies preserve the
|
|
24
|
+
* caller's endpoint order.
|
|
25
|
+
*
|
|
26
|
+
* @evidence contracts/common.md#principled-implementation Each table row is built from the same statistics record; `Math.trunc` on the value scaled by 100 truncates toward zero to two decimals, including negative elapsed values after a wall-clock adjustment. `en-US` fixes separators, and an absent CPU model is displayed as `unknown`.
|
|
27
|
+
* @evidence contracts/common.md#clear-and-simple-design Small local helpers (`integer`, `format`, `row`, `line`) share the formatting rules inside one function, so one place decides how a number reads.
|
|
28
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The report states only the report's measurements and supplied host facts; nothing describes an unmeasured backend server or changes foreign runtime methods.
|
|
29
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the locale, the truncation, and the CPU fallback.
|
|
30
|
+
*/
|
|
31
|
+
DynamicBenchmarkReporter.markdown = (report, host) => {
|
|
11
32
|
var _a;
|
|
12
|
-
var _b;
|
|
13
33
|
// one fixed locale, so a report reads the same on every machine
|
|
14
34
|
const integer = (value) => value.toLocaleString("en-US");
|
|
15
35
|
const format = (value) => value === null
|
|
16
36
|
? "N/A"
|
|
17
|
-
: (Math.
|
|
37
|
+
: (Math.trunc(value * 100) / 100).toLocaleString("en-US");
|
|
18
38
|
const head = () => [
|
|
19
39
|
"Type",
|
|
20
40
|
"Count",
|
|
@@ -41,10 +61,9 @@ var DynamicBenchmarkReporter;
|
|
|
41
61
|
"> Generated by [`@nestia/benchmark`](https://github.com/samchon/nestia)",
|
|
42
62
|
``,
|
|
43
63
|
` - Specifications`,
|
|
44
|
-
|
|
45
|
-
` -
|
|
46
|
-
` -
|
|
47
|
-
` - NodeJS Version: ${process.version}`,
|
|
64
|
+
` - CPU: ${(_a = host.cpu) !== null && _a !== void 0 ? _a : "unknown"}`,
|
|
65
|
+
` - RAM: ${integer(Math.floor(host.memory / 1024 / 1024 / 1024))} GB`,
|
|
66
|
+
` - NodeJS Version: ${host.node}`,
|
|
48
67
|
` - Arguments`,
|
|
49
68
|
` - Count: ${integer(report.count)}`,
|
|
50
69
|
` - Threads: ${integer(report.threads)}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DynamicBenchmarkReporter.js","sourceRoot":"","sources":["../../src/internal/DynamicBenchmarkReporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DynamicBenchmarkReporter.js","sourceRoot":"","sources":["../../src/internal/DynamicBenchmarkReporter.ts"],"names":[],"mappings":"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"}
|