Skip to content

Commit

Permalink
fix: add upper/lower values to BMF throughput
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <[email protected]>
  • Loading branch information
jerome-benoit committed Oct 2, 2024
1 parent d345504 commit 406e14b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
24 changes: 21 additions & 3 deletions src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export const gc = (() => {
export const convertReportToBmf = report => {
return report.benchmarks
.map(({ name, stats }) => {
const throughputSd = ratioStandardDeviation(1e9, 0, stats.avg, stats.sd)
return {
[name]: {
latency: {
Expand All @@ -145,6 +146,8 @@ export const convertReportToBmf = report => {
},
throughput: {
value: stats?.iters,
lower_value: stats?.iters - throughputSd,
upper_value: stats?.iters + throughputSd,
},
},
}
Expand Down Expand Up @@ -297,6 +300,13 @@ export async function measure(fn, opts = {}) {
return buildStats(samples)
}

const variance = (samples, avg = average(samples)) => {
return (
samples.reduce((a, b) => a + (b - avg) ** 2, 0) /
checkDividend(samples.length - 1) // Bessel's correction
)
}

const quantileSorted = (samples, q) => {
if (!Array.isArray(samples)) {
throw new TypeError(`expected array, got ${samples.constructor.name}`)
Expand Down Expand Up @@ -358,9 +368,7 @@ const buildStats = samples => {

const time = samples.reduce((a, b) => a + b, 0)
const avg = time / samples.length
const vr =
samples.reduce((a, b) => a + (b - avg) ** 2, 0) /
checkDividend(samples.length - 1) // Bessel's correction
const vr = variance(samples, avg)
const sd = Math.sqrt(vr)
const sem = sd / Math.sqrt(samples.length)
const critical =
Expand All @@ -386,3 +394,13 @@ const buildStats = samples => {
ss: samples.length >= minimumSamples,
}
}

// https://en.wikipedia.org/wiki/Propagation_of_uncertainty#Example_formulae
export const ratioStandardDeviation = (avgA, sdA, avgB, sdB) => {
return (
(avgA / checkDividend(avgB)) *
Math.sqrt(
(sdA / checkDividend(avgA)) ** 2 + (sdB / checkDividend(avgB)) ** 2
)
)
}
15 changes: 7 additions & 8 deletions src/reporter/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
tTable,
tatamiNgGroup,
} from '../constants.js'
import { checkDividend } from '../lib.js'
import { checkDividend, ratioStandardDeviation } from '../lib.js'
import * as clr from './clr.js'
import { duration, errorMargin, itersPerSecond, speedRatio } from './fmt.js'

Expand Down Expand Up @@ -175,13 +175,12 @@ export function summary(benchmarks, { colors = true }) {
.filter(benchmark => benchmark !== baseline)
.map(benchmark => {
const ratio = benchmark.stats.avg / checkDividend(baseline.stats.avg)
// https://en.wikipedia.org/wiki/Propagation_of_uncertainty#Example_formulae
const ratioSd =
ratio *
Math.sqrt(
(baseline.stats.sd / checkDividend(baseline.stats.avg)) ** 2 +
(benchmark.stats.sd / checkDividend(benchmark.stats.avg)) ** 2
)
const ratioSd = ratioStandardDeviation(
benchmark.stats.avg,
benchmark.stats.sd,
baseline.stats.avg,
baseline.stats.sd
)
const ratioSem =
ratioSd /
checkDividend(
Expand Down

0 comments on commit 406e14b

Please sign in to comment.