Comparing version 2.6.0 to 2.7.0
@@ -23,2 +23,3 @@ /** | ||
constructor(bench: Bench, name: string, fn: Fn, opts?: FnOptions); | ||
private loop; | ||
/** | ||
@@ -246,2 +247,3 @@ * run the current task and write the results in `Task.result` object | ||
constructor(options?: Options); | ||
runTask(task: Task): Task | Promise<Task>; | ||
/** | ||
@@ -254,2 +256,7 @@ * run the added tasks that were registered using the | ||
/** | ||
* similar to the {@link run} method but runs concurrently rather than sequentially | ||
* default limit is Infinity | ||
*/ | ||
runConcurrently(limit?: number): Promise<Task[]>; | ||
/** | ||
* warmup the benchmark tasks. | ||
@@ -280,9 +287,3 @@ * This is not run by default by the {@link run} method. | ||
*/ | ||
table(): ({ | ||
'Task Name': string; | ||
'ops/sec': string; | ||
'Average Time (ns)': string | number; | ||
Margin: string; | ||
Samples: string | number; | ||
} | null)[]; | ||
table(convert?: (task: Task) => Record<string, string | number> | undefined): (Record<string, string | number> | null)[]; | ||
/** | ||
@@ -289,0 +290,0 @@ * (getter) tasks results as an array |
@@ -1,10 +0,10 @@ | ||
var z = Object.defineProperty; | ||
var P = (s, r, t) => r in s ? z(s, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[r] = t; | ||
var i = (s, r, t) => (P(s, typeof r != "symbol" ? r + "" : r, t), t); | ||
var S = Object.defineProperty; | ||
var P = (s, a, t) => a in s ? S(s, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[a] = t; | ||
var i = (s, a, t) => (P(s, typeof a != "symbol" ? a + "" : a, t), t); | ||
// src/event.ts | ||
function a(s, r = null) { | ||
function r(s, a = null) { | ||
let t = new Event(s); | ||
return Object.defineProperty(t, "task", { | ||
value: r, | ||
return a && Object.defineProperty(t, "task", { | ||
value: a, | ||
enumerable: !0, | ||
@@ -17,3 +17,3 @@ writable: !1, | ||
// src/constants.ts | ||
var q = { | ||
var C = { | ||
1: 12.71, | ||
@@ -140,12 +140,12 @@ 2: 4.303, | ||
infinity: 1.96 | ||
}, T = q; | ||
}, g = C; | ||
// src/utils.ts | ||
var V = (s) => s / 1e6, C = () => V(Number(process.hrtime.bigint())), g = () => performance.now(); | ||
function $(s) { | ||
var H = (s) => s / 1e6, j = () => H(Number(process.hrtime.bigint())), b = () => performance.now(); | ||
function z(s) { | ||
return s !== null && typeof s == "object" && typeof s.then == "function"; | ||
} | ||
var R = (s) => s.reduce((r, t) => r + t, 0) / s.length || 0, O = (s, r) => s.reduce((e, n) => e + (n - r) ** 2, 0) / (s.length - 1) || 0, D = (async () => { | ||
}).constructor, G = (s) => s.constructor === D, k = async (s) => { | ||
if (G(s.fn)) | ||
var M = (s, a) => s.reduce((e, n) => e + (n - a) ** 2, 0) / (s.length - 1) || 0, q = (async () => { | ||
}).constructor, V = (s) => s.constructor === q, O = async (s) => { | ||
if (V(s.fn)) | ||
return !0; | ||
@@ -158,6 +158,6 @@ try { | ||
} | ||
let r = s.fn(), t = $(r); | ||
let a = s.fn(), t = z(a); | ||
if (t) | ||
try { | ||
await r; | ||
await a; | ||
} catch (e) { | ||
@@ -171,3 +171,3 @@ } | ||
return t; | ||
} catch (r) { | ||
} catch (a) { | ||
return !1; | ||
@@ -179,3 +179,3 @@ } | ||
var p = class extends EventTarget { | ||
constructor(t, e, n, h = {}) { | ||
constructor(t, e, n, o = {}) { | ||
super(); | ||
@@ -188,31 +188,29 @@ i(this, "bench"); | ||
i(this, "opts"); | ||
this.bench = t, this.name = e, this.fn = n, this.opts = h; | ||
this.bench = t, this.name = e, this.fn = n, this.opts = o; | ||
} | ||
async run() { | ||
var h, c, m, f; | ||
this.dispatchEvent(a("start", this)); | ||
let t = 0, e = []; | ||
if (await this.bench.setup(this, "run"), this.opts.beforeAll != null) | ||
async loop(t, e) { | ||
var l; | ||
let n = 0, o = []; | ||
if (this.opts.beforeAll != null) | ||
try { | ||
await this.opts.beforeAll.call(this); | ||
} catch (o) { | ||
this.setResult({ error: o }); | ||
} catch (h) { | ||
return { error: h }; | ||
} | ||
let n = await k(this); | ||
let u = await O(this); | ||
try { | ||
for (; (t < this.bench.time || this.runs < this.bench.iterations) && !((h = this.bench.signal) != null && h.aborted); ) { | ||
for (; (n < t || o.length < e) && !((l = this.bench.signal) != null && l.aborted); ) { | ||
this.opts.beforeEach != null && await this.opts.beforeEach.call(this); | ||
let o = 0; | ||
if (n) { | ||
let l = this.bench.now(); | ||
await this.fn.call(this), o = this.bench.now() - l; | ||
let h = 0; | ||
if (u) { | ||
let c = this.bench.now(); | ||
await this.fn.call(this), h = this.bench.now() - c; | ||
} else { | ||
let l = this.bench.now(); | ||
this.fn.call(this), o = this.bench.now() - l; | ||
let c = this.bench.now(); | ||
this.fn.call(this), h = this.bench.now() - c; | ||
} | ||
e.push(o), this.runs += 1, t += o, this.opts.afterEach != null && await this.opts.afterEach.call(this); | ||
o.push(h), n += h, this.opts.afterEach != null && await this.opts.afterEach.call(this); | ||
} | ||
} catch (o) { | ||
if (this.setResult({ error: o }), this.bench.throws) | ||
throw o; | ||
} catch (h) { | ||
return { error: h }; | ||
} | ||
@@ -222,71 +220,55 @@ if (this.opts.afterAll != null) | ||
await this.opts.afterAll.call(this); | ||
} catch (o) { | ||
this.setResult({ error: o }); | ||
} catch (h) { | ||
return { error: h }; | ||
} | ||
if (await this.bench.teardown(this, "run"), !((c = this.result) != null && c.error)) { | ||
e.sort((H, j) => H - j); | ||
let o = t / this.runs, l = 1e3 / o, u = e.length, E = u - 1, F = e[0], B = e[E], b = R(e), y = O(e, b), A = Math.sqrt(y), x = A / Math.sqrt(u), L = T[String(Math.round(E) || 1)] || T.infinity, M = x * L, K = M / b * 100, N = e[Math.ceil(u * 0.75) - 1], _ = e[Math.ceil(u * 0.99) - 1], S = e[Math.ceil(u * 0.995) - 1], I = e[Math.ceil(u * 0.999) - 1]; | ||
if ((m = this.bench.signal) != null && m.aborted) | ||
return { samples: o }; | ||
} | ||
async run() { | ||
var n, o; | ||
if ((n = this.result) != null && n.error) | ||
return this; | ||
this.dispatchEvent(r("start", this)), await this.bench.setup(this, "run"); | ||
let { samples: t, error: e } = await this.loop(this.bench.time, this.bench.iterations); | ||
if (this.bench.teardown(this, "run"), t) { | ||
let u = t.reduce((E, T) => E + T, 0); | ||
this.runs = t.length, t.sort((E, T) => E - T); | ||
let l = u / this.runs, h = 1e3 / l, c = t.length, m = c - 1, F = t[0], R = t[m], w = u / t.length || 0, k = M(t, w), y = Math.sqrt(k), x = y / Math.sqrt(c), A = g[String(Math.round(m) || 1)] || g.infinity, L = x * A, B = L / w * 100, _ = t[Math.ceil(c * 0.75) - 1], K = t[Math.ceil(c * 0.99) - 1], N = t[Math.ceil(c * 0.995) - 1], I = t[Math.ceil(c * 0.999) - 1]; | ||
if ((o = this.bench.signal) != null && o.aborted) | ||
return this; | ||
this.setResult({ | ||
totalTime: t, | ||
totalTime: u, | ||
min: F, | ||
max: B, | ||
hz: l, | ||
period: o, | ||
samples: e, | ||
mean: b, | ||
variance: y, | ||
sd: A, | ||
max: R, | ||
hz: h, | ||
period: l, | ||
samples: t, | ||
mean: w, | ||
variance: k, | ||
sd: y, | ||
sem: x, | ||
df: E, | ||
critical: L, | ||
moe: M, | ||
rme: K, | ||
p75: N, | ||
p99: _, | ||
p995: S, | ||
df: m, | ||
critical: A, | ||
moe: L, | ||
rme: B, | ||
p75: _, | ||
p99: K, | ||
p995: N, | ||
p999: I | ||
}); | ||
} | ||
return (f = this.result) != null && f.error && (this.dispatchEvent(a("error", this)), this.bench.dispatchEvent(a("error", this))), this.dispatchEvent(a("cycle", this)), this.bench.dispatchEvent(a("cycle", this)), this.dispatchEvent(a("complete", this)), this; | ||
if (e) { | ||
if (this.setResult({ error: e }), this.bench.throws) | ||
throw e; | ||
this.dispatchEvent(r("error", this)), this.bench.dispatchEvent(r("error", this)); | ||
} | ||
return this.dispatchEvent(r("cycle", this)), this.bench.dispatchEvent(r("cycle", this)), this.dispatchEvent(r("complete", this)), this; | ||
} | ||
async warmup() { | ||
var h; | ||
this.dispatchEvent(a("warmup", this)); | ||
let t = this.bench.now(), e = 0; | ||
if (await this.bench.setup(this, "warmup"), this.opts.beforeAll != null) | ||
try { | ||
await this.opts.beforeAll.call(this); | ||
} catch (c) { | ||
this.setResult({ error: c }); | ||
} | ||
let n = await k(this); | ||
for (; (e < this.bench.warmupTime || this.runs < this.bench.warmupIterations) && !((h = this.bench.signal) != null && h.aborted); ) { | ||
if (this.opts.beforeEach != null) | ||
try { | ||
await this.opts.beforeEach.call(this); | ||
} catch (c) { | ||
this.setResult({ error: c }); | ||
} | ||
try { | ||
n ? await this.fn.call(this) : this.fn.call(this); | ||
} catch (c) { | ||
if (this.bench.throws) | ||
throw c; | ||
} | ||
if (this.runs += 1, e = this.bench.now() - t, this.opts.afterEach != null) | ||
try { | ||
await this.opts.afterEach.call(this); | ||
} catch (c) { | ||
this.setResult({ error: c }); | ||
} | ||
} | ||
if (this.opts.afterAll != null) | ||
try { | ||
await this.opts.afterAll.call(this); | ||
} catch (c) { | ||
this.setResult({ error: c }); | ||
} | ||
this.bench.teardown(this, "warmup"), this.runs = 0; | ||
var e; | ||
if ((e = this.result) != null && e.error) | ||
return; | ||
this.dispatchEvent(r("warmup", this)), await this.bench.setup(this, "warmup"); | ||
let { error: t } = await this.loop(this.bench.warmupTime, this.bench.warmupIterations); | ||
if (this.bench.teardown(this, "warmup"), t && (this.setResult({ error: t }), this.bench.throws)) | ||
throw t; | ||
} | ||
@@ -300,6 +282,6 @@ addEventListener(t, e, n) { | ||
setResult(t) { | ||
this.result = { ...this.result, ...t }, Object.freeze(this.reset); | ||
this.result = { ...this.result, ...t }, Object.freeze(this.result); | ||
} | ||
reset() { | ||
this.dispatchEvent(a("reset", this)), this.runs = 0, this.result = void 0; | ||
this.dispatchEvent(r("reset", this)), this.runs = 0, this.result = void 0; | ||
} | ||
@@ -309,5 +291,5 @@ }; | ||
// src/bench.ts | ||
var w = class extends EventTarget { | ||
var v = class extends EventTarget { | ||
constructor(t = {}) { | ||
var e, n, h, c, m, f, o, l; | ||
var e, n, o, u, l, h, c, m; | ||
super(); | ||
@@ -322,11 +304,11 @@ i(this, "_tasks", /* @__PURE__ */ new Map()); | ||
i(this, "iterations", 10); | ||
i(this, "now", g); | ||
i(this, "now", b); | ||
i(this, "setup"); | ||
i(this, "teardown"); | ||
this.now = (e = t.now) != null ? e : this.now, this.warmupTime = (n = t.warmupTime) != null ? n : this.warmupTime, this.warmupIterations = (h = t.warmupIterations) != null ? h : this.warmupIterations, this.time = (c = t.time) != null ? c : this.time, this.iterations = (m = t.iterations) != null ? m : this.iterations, this.signal = t.signal, this.throws = (f = t.throws) != null ? f : !1, this.setup = (o = t.setup) != null ? o : () => { | ||
}, this.teardown = (l = t.teardown) != null ? l : () => { | ||
this.now = (e = t.now) != null ? e : this.now, this.warmupTime = (n = t.warmupTime) != null ? n : this.warmupTime, this.warmupIterations = (o = t.warmupIterations) != null ? o : this.warmupIterations, this.time = (u = t.time) != null ? u : this.time, this.iterations = (l = t.iterations) != null ? l : this.iterations, this.signal = t.signal, this.throws = (h = t.throws) != null ? h : !1, this.setup = (c = t.setup) != null ? c : () => { | ||
}, this.teardown = (m = t.teardown) != null ? m : () => { | ||
}, this.signal && this.signal.addEventListener( | ||
"abort", | ||
() => { | ||
this.dispatchEvent(a("abort")); | ||
this.dispatchEvent(r("abort")); | ||
}, | ||
@@ -336,12 +318,30 @@ { once: !0 } | ||
} | ||
runTask(t) { | ||
var e; | ||
return (e = this.signal) != null && e.aborted ? t : t.run(); | ||
} | ||
async run() { | ||
var e; | ||
this.dispatchEvent(a("start")); | ||
this.dispatchEvent(r("start")); | ||
let t = []; | ||
for (let n of [...this._tasks.values()]) | ||
(e = this.signal) != null && e.aborted ? t.push(n) : t.push(await n.run()); | ||
return this.dispatchEvent(a("complete")), t; | ||
for (let e of [...this._tasks.values()]) | ||
t.push(await this.runTask(e)); | ||
return this.dispatchEvent(r("complete")), t; | ||
} | ||
async runConcurrently(t = 1 / 0) { | ||
this.dispatchEvent(r("start")); | ||
let e = [...this._tasks.values()], n = []; | ||
return await (async () => { | ||
for (; e.length > 0; ) { | ||
let u = []; | ||
for (; u.length < t && e.length > 0; ) { | ||
let h = e.pop(); | ||
u.push(this.runTask(h)); | ||
} | ||
let l = await Promise.all(u); | ||
n.push(...l); | ||
} | ||
})(), this.dispatchEvent(r("complete")), n; | ||
} | ||
async warmup() { | ||
this.dispatchEvent(a("warmup")); | ||
this.dispatchEvent(r("warmup")); | ||
for (let [, t] of this._tasks) | ||
@@ -351,3 +351,3 @@ await t.warmup(); | ||
reset() { | ||
this.dispatchEvent(a("reset")), this._tasks.forEach((t) => { | ||
this.dispatchEvent(r("reset")), this._tasks.forEach((t) => { | ||
t.reset(); | ||
@@ -357,13 +357,13 @@ }); | ||
add(t, e, n = {}) { | ||
let h = new p(this, t, e, n); | ||
return this._tasks.set(t, h), this.dispatchEvent(a("add", h)), this; | ||
let o = new p(this, t, e, n); | ||
return this._tasks.set(t, o), this.dispatchEvent(r("add", o)), this; | ||
} | ||
todo(t, e = () => { | ||
}, n = {}) { | ||
let h = new p(this, t, e, n); | ||
return this._todos.set(t, h), this.dispatchEvent(a("todo", h)), this; | ||
let o = new p(this, t, e, n); | ||
return this._todos.set(t, o), this.dispatchEvent(r("todo", o)), this; | ||
} | ||
remove(t) { | ||
let e = this.getTask(t); | ||
return e && (this.dispatchEvent(a("remove", e)), this._tasks.delete(t)), this; | ||
return e && (this.dispatchEvent(r("remove", e)), this._tasks.delete(t)), this; | ||
} | ||
@@ -376,10 +376,17 @@ addEventListener(t, e, n) { | ||
} | ||
table() { | ||
return this.tasks.map(({ name: t, result: e }) => e ? { | ||
"Task Name": t, | ||
"ops/sec": e.error ? "NaN" : parseInt(e.hz.toString(), 10).toLocaleString(), | ||
"Average Time (ns)": e.error ? "NaN" : e.mean * 1e3 * 1e3, | ||
Margin: e.error ? "NaN" : `\xB1${e.rme.toFixed(2)}%`, | ||
Samples: e.error ? "NaN" : e.samples.length | ||
} : null); | ||
table(t) { | ||
return this.tasks.map((e) => { | ||
if (e.result) { | ||
if (e.result.error) | ||
throw e.result.error; | ||
return (t == null ? void 0 : t(e)) || { | ||
"Task Name": e.name, | ||
"ops/sec": e.result.error ? "NaN" : parseInt(e.result.hz.toString(), 10).toLocaleString(), | ||
"Average Time (ns)": e.result.error ? "NaN" : e.result.mean * 1e3 * 1e3, | ||
Margin: e.result.error ? "NaN" : `\xB1${e.result.rme.toFixed(2)}%`, | ||
Samples: e.result.error ? "NaN" : e.result.samples.length | ||
}; | ||
} | ||
return null; | ||
}); | ||
} | ||
@@ -401,9 +408,9 @@ get results() { | ||
// src/index.ts | ||
var ot = w; | ||
var rt = v; | ||
export { | ||
w as Bench, | ||
v as Bench, | ||
p as Task, | ||
ot as default, | ||
C as hrtimeNow, | ||
g as now | ||
rt as default, | ||
j as hrtimeNow, | ||
b as now | ||
}; |
{ | ||
"name": "tinybench", | ||
"version": "2.6.0", | ||
"version": "2.7.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "packageManager": "pnpm@8.4.0", |
@@ -62,5 +62,3 @@ | ||
console.table( | ||
bench.todos.map(({ name }) => ({ | ||
'Task name': name, | ||
})), | ||
bench.table((task) => ({'Task name': task.name})) | ||
); | ||
@@ -147,2 +145,3 @@ | ||
- `async run()`: run the added tasks that were registered using the `add` method | ||
- `async runConcurrently(limit: number = Infinity)`: similar to the `run` method but runs concurrently rather than sequentially | ||
- `async warmup()`: warm up the benchmark tasks | ||
@@ -149,0 +148,0 @@ - `reset()`: reset each task and remove its result |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42902
1117
402