Skip to content

Commit 37b78db

Browse files
authored
feat: export formatNumber, add documentation for converting the result for console.table (#444)
* feat: export formatNumber, add documentation for converting the results for console.table * fix
1 parent 39491c8 commit 37b78db

File tree

2 files changed

+111
-53
lines changed

2 files changed

+111
-53
lines changed

README.md

Lines changed: 110 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -100,58 +100,6 @@ task.addEventListener('cycle', (evt) => {
100100

101101
### [`BenchEvent`](https://tinylibs.github.io/tinybench/types/BenchEvent.html)
102102

103-
## Timestamp Providers
104-
105-
Tinybench can utilize different timestamp providers for measuring time intervals.
106-
By default it uses `performance.now()`.
107-
108-
The `timestampProvider` option can be set when creating a `Bench` instance. It
109-
accepts either a `TimestampProvider` object or shorthands for the common
110-
providers `hrtimeNow` and `performanceNow`.
111-
112-
If you use `bun` runtime, you can also use `bunNanoseconds` shorthand.
113-
114-
You can set the `timestampProvider` to `auto` to let Tinybench choose the most
115-
precise available timestamp provider based on the runtime.
116-
117-
```ts
118-
import { Bench } from 'tinybench'
119-
120-
const bench = new Bench({
121-
timestampProvider: 'hrtimeNow' // or 'performanceNow', 'bunNanoseconds', 'auto'
122-
})
123-
```
124-
125-
If you want to provide a custom timestamp provider, you can create an object that implements
126-
the `TimestampProvider` interface:
127-
128-
```ts
129-
import { Bench, TimestampProvider } from 'tinybench'
130-
131-
// Custom timestamp provider using Date.now()
132-
const dateNowTimestampProvider: TimestampProvider = {
133-
name: 'dateNow', // name of the provider
134-
fn: Date.now, // function that returns the current timestamp
135-
toMs: ts => ts, // convert the timestamp to milliseconds
136-
fromMs: ts => ts // convert milliseconds to the format used by fn()
137-
}
138-
139-
const bench = new Bench({
140-
timestampProvider: dateNowTimestampProvider
141-
})
142-
```
143-
144-
You can also set the `now` option to a function that returns the current timestamp.
145-
It will be converted to a `TimestampProvider` internally.
146-
147-
```ts
148-
import { Bench } from 'tinybench'
149-
150-
const bench = new Bench({
151-
now: Date.now
152-
})
153-
```
154-
155103
## Async Detection
156104

157105
Tinybench automatically detects if a task function is asynchronous by
@@ -198,6 +146,64 @@ bench.concurrency = 'task' // The concurrency mode to determine how tasks are ru
198146
await bench.run()
199147
```
200148

149+
## Convert task results for `console.table()`
150+
151+
You can convert the benchmark results to a table format suitable for
152+
`console.table()` using the `bench.table()` method.
153+
154+
```ts
155+
const table = bench.table()
156+
console.table(table)
157+
```
158+
159+
You can also customize the table output by providing a convert-function to the `table` method.
160+
161+
```ts
162+
import { Bench, type ConsoleTableConverter, formatNumber, mToNs, type Task } from 'tinybench'
163+
164+
/**
165+
* The default converter function for console.table output.
166+
* Modify it as needed to customize the table format.
167+
*/
168+
const defaultConverter: ConsoleTableConverter = (
169+
task: Task
170+
): Record<string, number | string> => {
171+
const state = task.result.state
172+
return {
173+
'Task name': task.name,
174+
...(state === 'aborted-with-statistics' || state === 'completed'
175+
? {
176+
'Latency avg (ns)': `${formatNumber(mToNs(task.result.latency.mean))} \xb1 ${task.result.latency.rme.toFixed(2)}%`,
177+
'Latency med (ns)': `${formatNumber(mToNs(task.result.latency.p50))} \xb1 ${formatNumber(mToNs(task.result.latency.mad))}`,
178+
'Throughput avg (ops/s)': `${Math.round(task.result.throughput.mean).toString()} \xb1 ${task.result.throughput.rme.toFixed(2)}%`,
179+
'Throughput med (ops/s)': `${Math.round(task.result.throughput.p50).toString()} \xb1 ${Math.round(task.result.throughput.mad).toString()}`,
180+
Samples: task.result.latency.samplesCount,
181+
}
182+
: state !== 'errored'
183+
? {
184+
'Latency avg (ns)': 'N/A',
185+
'Latency med (ns)': 'N/A',
186+
'Throughput avg (ops/s)': 'N/A',
187+
'Throughput med (ops/s)': 'N/A',
188+
Samples: 'N/A',
189+
Remarks: state,
190+
}
191+
: {
192+
Error: task.result.error.message,
193+
Stack: task.result.error.stack ?? 'N/A',
194+
}),
195+
...(state === 'aborted-with-statistics' && {
196+
Remarks: state,
197+
}),
198+
}
199+
}
200+
201+
const bench = new Bench({ name: 'custom table benchmark', time: 100 })
202+
// add tasks...
203+
204+
console.table(bench.table(defaultConverter))
205+
```
206+
201207
## Retaining Samples
202208

203209
By default Tinybench does not keep the samples for `latency` and `throughput` to
@@ -220,6 +226,58 @@ bench.add('task with samples', () => {
220226
}, { retainSamples: true })
221227
```
222228

229+
## Timestamp Providers
230+
231+
Tinybench can utilize different timestamp providers for measuring time intervals.
232+
By default it uses `performance.now()`.
233+
234+
The `timestampProvider` option can be set when creating a `Bench` instance. It
235+
accepts either a `TimestampProvider` object or shorthands for the common
236+
providers `hrtimeNow` and `performanceNow`.
237+
238+
If you use `bun` runtime, you can also use `bunNanoseconds` shorthand.
239+
240+
You can set the `timestampProvider` to `auto` to let Tinybench choose the most
241+
precise available timestamp provider based on the runtime.
242+
243+
```ts
244+
import { Bench } from 'tinybench'
245+
246+
const bench = new Bench({
247+
timestampProvider: 'hrtimeNow' // or 'performanceNow', 'bunNanoseconds', 'auto'
248+
})
249+
```
250+
251+
If you want to provide a custom timestamp provider, you can create an object that implements
252+
the `TimestampProvider` interface:
253+
254+
```ts
255+
import { Bench, TimestampProvider } from 'tinybench'
256+
257+
// Custom timestamp provider using Date.now()
258+
const dateNowTimestampProvider: TimestampProvider = {
259+
name: 'dateNow', // name of the provider
260+
fn: Date.now, // function that returns the current timestamp
261+
toMs: ts => ts, // convert the timestamp to milliseconds
262+
fromMs: ts => ts // convert milliseconds to the format used by fn()
263+
}
264+
265+
const bench = new Bench({
266+
timestampProvider: dateNowTimestampProvider
267+
})
268+
```
269+
270+
You can also set the `now` option to a function that returns the current timestamp.
271+
It will be converted to a `TimestampProvider` internally.
272+
273+
```ts
274+
import { Bench } from 'tinybench'
275+
276+
const bench = new Bench({
277+
now: Date.now
278+
})
279+
```
280+
223281
## Aborting Benchmarks
224282

225283
Tinybench supports aborting benchmarks using `AbortSignal` at both the bench and task levels:

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ export type {
3737
TimestampProvider,
3838
TimestampValue,
3939
} from './types'
40-
export { hrtimeNow, performanceNow as now, nToMs } from './utils'
40+
export { formatNumber, hrtimeNow, performanceNow as now, nToMs } from './utils'

0 commit comments

Comments
 (0)