Skip to content

Commit

Permalink
feat: improve the latency and throughput formatting in the result tab…
Browse files Browse the repository at this point in the history
…le (#233)

Co-authored-by: Jérôme Benoit <[email protected]>
  • Loading branch information
pallosp and jerome-benoit authored Jan 29, 2025
1 parent 7bcc8c0 commit 366cf99
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { createBenchEvent } from './event'
import { Task } from './task'
import {
formatNumber,
invariant,
type JSRuntime,
mToNs,
Expand Down Expand Up @@ -254,12 +255,12 @@ export class Bench extends EventTarget {
}
: (convert?.(task) ?? {
'Task name': task.name,
'Latency average (ns)': `${mToNs(task.result.latency.mean).toFixed(2)} \xb1 ${task.result.latency.rme.toFixed(2)}%`,
'Latency average (ns)': `${formatNumber(mToNs(task.result.latency.mean), 5, 2)} \xb1 ${task.result.latency.rme.toFixed(2)}%`,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
'Latency median (ns)': `${mToNs(task.result.latency.p50!).toFixed(2)}${Number.parseFloat(mToNs(task.result.latency.mad!).toFixed(2)) > 0 ? ` \xb1 ${mToNs(task.result.latency.mad!).toFixed(2)}` : ''}`,
'Latency median (ns)': `${formatNumber(mToNs(task.result.latency.p50!), 5, 2)} \xb1 ${mToNs(task.result.latency.mad!).toFixed(2)}`,
'Throughput average (ops/s)': `${task.result.throughput.mean.toFixed(0)} \xb1 ${task.result.throughput.rme.toFixed(2)}%`,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
'Throughput median (ops/s)': `${task.result.throughput.p50!.toFixed(0)}${Number.parseInt(task.result.throughput.mad!.toFixed(0), 10) > 0 ? ` \xb1 ${task.result.throughput.mad!.toFixed(0)}` : ''}`,
'Throughput median (ops/s)': `{Math.round(task.result.throughput.p50!)} \xb1 ${Math.round(task.result.throughput.mad)}`,

Check failure on line 263 in src/bench.ts

View workflow job for this annotation

GitHub Actions / Node.js 18 QA on ubuntu-latest

Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

Check failure on line 263 in src/bench.ts

View workflow job for this annotation

GitHub Actions / Node.js 20 QA on ubuntu-latest

Argument of type 'number | undefined' is not assignable to parameter of type 'number'.

Check failure on line 263 in src/bench.ts

View workflow job for this annotation

GitHub Actions / Node.js 22 QA on ubuntu-latest

Argument of type 'number | undefined' is not assignable to parameter of type 'number'.
Samples: task.result.latency.samples.length,
})
/* eslint-enable perfectionist/sort-objects */
Expand Down
23 changes: 23 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,29 @@ export const nToMs = (ns: number) => ns / 1e6
*/
export const mToNs = (ms: number) => ms * 1e6

/**
* @param x number to format
* @param targetDigits number of digits in the output to aim for
* @param maxFractionDigits hard limit for the number of digits after the decimal dot
* @returns formatted number
*/
export const formatNumber = (x: number, targetDigits: number, maxFractionDigits: number): string => {
// Round large numbers to integers, but not to multiples of 10.
// The actual number of significant digits may be more than `targetDigits`.
if (Math.abs(x) >= 10 ** targetDigits) {
return x.toFixed()
}

// Round small numbers to have `maxFractionDigits` digits after the decimal dot.
// The actual number of significant digits may be less than `targetDigits`.
if (Math.abs(x) < 10 ** (targetDigits - maxFractionDigits)) {
return x.toFixed(maxFractionDigits)
}

// Round medium magnitude numbers to have exactly `targetDigits` significant digits.
return x.toPrecision(targetDigits)
}

let hrtimeBigint: () => bigint
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
if (typeof (globalThis as any).process?.hrtime?.bigint === 'function') {
Expand Down
22 changes: 22 additions & 0 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
import { expect, test } from 'vitest'

import { getStatisticsSorted } from '../src/utils'
import { formatNumber } from '../src/utils'


test('formatting integers', () => {
expect(formatNumber(123456, 5, 2)).toBe('123456')
expect(formatNumber(12345, 5, 2)).toBe('12345')
expect(formatNumber(1234, 5, 2)).toBe('1234.0')
expect(formatNumber(123, 5, 2)).toBe('123.00')
expect(formatNumber(12, 5, 2)).toBe('12.00')
expect(formatNumber(1, 5, 2)).toBe('1.00')
expect(formatNumber(0, 5, 2)).toBe('0.00')
expect(formatNumber(-1, 5, 2)).toBe('-1.00')
})

test('formatting floats', () => {
expect(formatNumber(123456.789, 5, 2)).toBe('123457')
expect(formatNumber(12345.6789, 5, 2)).toBe('12346')
expect(formatNumber(1234.56789, 5, 2)).toBe('1234.6')
expect(formatNumber(123.456789, 5, 2)).toBe('123.46')
expect(formatNumber(12.3456789, 5, 2)).toBe('12.35')
expect(formatNumber(-12.3456789, 5, 2)).toBe('-12.35')
})

test('median absolute deviation', () => {
// https://www.wolframalpha.com/input?i=MedianDeviation[1,2,3]
Expand Down

0 comments on commit 366cf99

Please sign in to comment.