Skip to content

Commit cf96c3d

Browse files
authored
feat: add several code refactor/fixes (#123)
* fix(clock): use util.debuglog and declare plugin template vars Replace incorrect util.debug usage with util.debuglog('benchmark') and declare newCode/functionToCall during plugin template generation. * fix(plugins): declare loop variable in validatePlugins Use 'for (const p of plugins)' to avoid leaking loop variable. * fix(reporter): format ops/sec as numbers for Intl.NumberFormat Pass numbers (not stringified .toFixed) to Intl.NumberFormat for consistent formatting. * fix(html): avoid timer shadowing and use real timer.format Import real timer from clock and rename local number formatter; use timer.format for ns min/max. * fix(validation): enforce exclusive minTime > 1e-6 and min bounds Make minTime strictly greater than 1e-6; enforce repeatSuite and minSamples minimums. * test(copy): increase minSamples to reduce variance Raise minSamples to stabilize same-function comparison.
1 parent 2d7ba17 commit cf96c3d

File tree

8 files changed

+23
-28
lines changed

8 files changed

+23
-28
lines changed

lib/clock.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
const { debug, types } = require("node:util");
1+
const { debuglog } = require("node:util");
22
const { validateNumber } = require("./validators");
33

4-
let debugBench = debug("benchmark", (fn) => {
5-
debugBench = fn;
6-
});
4+
const debugBench = debuglog("benchmark");
75

86
const kUnmanagedTimerResult = Symbol("kUnmanagedTimerResult");
97

@@ -137,7 +135,7 @@ const duration = Number(${varNames.timer}.now() - startedAt);
137135

138136
for (const p of bench.plugins) {
139137
if (typeof p.afterClockTemplate === "function") {
140-
[newCode] = p.afterClockTemplate(varNames);
138+
const [newCode] = p.afterClockTemplate(varNames);
141139
code += newCode;
142140
}
143141
}
@@ -163,7 +161,7 @@ let ${varNames.context} = {};
163161
const wrapFunctions = [];
164162
for (const p of bench.plugins) {
165163
if (typeof p.beforeClockTemplate === "function") {
166-
[newCode, functionToCall] = p.beforeClockTemplate(varNames);
164+
const [newCode, functionToCall] = p.beforeClockTemplate(varNames);
167165
code += newCode;
168166
if (functionToCall) {
169167
wrapFunctions.push(functionToCall);
@@ -180,7 +178,7 @@ const result = ${varNames.timer}[kUnmanagedTimerResult](${varNames.context});
180178
`;
181179
for (const p of bench.plugins) {
182180
if (typeof p.afterClockTemplate === "function") {
183-
[newCode] = p.afterClockTemplate(varNames);
181+
const [newCode] = p.afterClockTemplate(varNames);
184182
code += newCode;
185183
}
186184
}

lib/index.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,22 +153,15 @@ class Suite {
153153
...defaultBenchOptions,
154154
...options,
155155
};
156+
// Enforce strict minimum (> 1e-6s). Using EPSILON to make boundary exclusive.
156157
validateNumber(
157158
options.minTime,
158159
"options.minTime",
159-
timer.resolution * 1e3,
160+
timer.resolution * 1e3 + Number.EPSILON,
160161
);
161162
validateNumber(options.maxTime, "options.maxTime", options.minTime);
162-
validateNumber(
163-
options.repeatSuite,
164-
"options.repeatSuite",
165-
options.repeatSuite,
166-
);
167-
validateNumber(
168-
options.minSamples,
169-
"options.minSamples",
170-
options.minSamples,
171-
);
163+
validateNumber(options.repeatSuite, "options.repeatSuite", 1);
164+
validateNumber(options.minSamples, "options.minSamples", 1);
172165
}
173166
validateFunction(fn, "fn");
174167

lib/plugins.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const { validateFunction, validateArray } = require("./validators");
1313
* @throws {Error} If any plugin doesn't meet the requirements or isn't supported
1414
*/
1515
function validatePlugins(plugins) {
16-
for (p of plugins) {
16+
for (const p of plugins) {
1717
validateFunction(p.isSupported, "Plugins must have a isSupported method.");
1818
validateFunction(p.toString, "Plugins must have a toString() method.");
1919

lib/reporter/chart.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ function drawBar(
2727

2828
if (metric === "opsSec") {
2929
percentage = value / total; // Higher ops/sec is better
30-
const valueReported = value < 100 ? value.toFixed(2) : value.toFixed(0);
30+
const valueReported =
31+
value < 100 ? Number(value.toFixed(2)) : Math.round(value);
3132
displayedValue = styleText(["yellow"], formatter.format(valueReported));
3233
displayedMetric = "ops/sec";
3334
} else {

lib/reporter/html.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ const { platform, arch, availableParallelism, totalmem } = require("node:os");
22
const fs = require("node:fs");
33
const path = require("node:path");
44
const { summarize } = require("../utils/analyze");
5+
const { timer } = require("../clock");
56

67
const formatter = Intl.NumberFormat(undefined, {
78
notation: "standard",
89
maximumFractionDigits: 3,
910
});
1011

11-
const timer = Intl.NumberFormat(undefined, {
12+
const timeNumberFormat = Intl.NumberFormat(undefined, {
1213
minimumFractionDigits: 3,
1314
maximumFractionDigits: 3,
1415
});

lib/reporter/pretty.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,11 @@ function printResult(result, prefixLength) {
146146

147147
if (result.opsSec !== undefined) {
148148
const opsSecReported =
149-
result.opsSec < 100 ? result.opsSec.toFixed(2) : result.opsSec.toFixed(0);
149+
result.opsSec < 100
150+
? Number(result.opsSec.toFixed(2))
151+
: Math.round(result.opsSec);
150152
process.stdout.write(
151-
styleText([color, "bold"], `${formatter.format(opsSecReported)} ops/sec`),
153+
styleText(["bold"], `${formatter.format(opsSecReported)} ops/sec`),
152154
);
153155
} else if (result.totalTime !== undefined) {
154156
let timeFormatted;

lib/reporter/text.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function textReport(results, options = {}) {
2121
if (result.opsSec !== undefined) {
2222
const opsSecReported =
2323
result.opsSec < 100
24-
? result.opsSec.toFixed(2)
25-
: result.opsSec.toFixed(0);
24+
? Number(result.opsSec.toFixed(2))
25+
: Math.round(result.opsSec);
2626
process.stdout.write(
2727
styleText(
2828
["blue", "bold"],

test/fixtures/copy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ const { Suite } = require("../../lib");
33
const suite = new Suite({ reporter: false });
44

55
suite
6-
.add("Using includes", () => {
6+
.add("Using includes", { minSamples: 20 }, () => {
77
const text =
88
"text/html,application/xhtml+xml,application/xml;application/json;q=0.9,image/avif,image/webp,*/*;q=0.8";
99
const r = text.includes("application/json");
1010
})
11-
.add("Using includes 2", () => {
11+
.add("Using includes 2", { minSamples: 20 }, () => {
1212
const text =
1313
"text/html,application/xhtml+xml,application/xml;application/json;q=0.9,image/avif,image/webp,*/*;q=0.8";
1414
const r = text.includes("application/json");
1515
})
16-
.add("Using includes 3", () => {
16+
.add("Using includes 3", { minSamples: 20 }, () => {
1717
const text =
1818
"text/html,application/xhtml+xml,application/xml;application/json;q=0.9,image/avif,image/webp,*/*;q=0.8";
1919
const r = text.includes("application/json");

0 commit comments

Comments
 (0)