From f64e11996f56869c486ba5bb97d7d2de999b9200 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Mon, 27 May 2019 10:00:00 +0200 Subject: [PATCH] Add benchmarking --- benchmarks/array.js | 7 +++++++ benchmarks/main.js | 22 +++++++++++----------- benchmarks/mean.js | 12 ++++++++++++ benchmarks/measure.js | 13 +++++++++++++ benchmarks/print.js | 15 +++++++++++++++ benchmarks/promise.js | 18 ++++++++++++++++++ benchmarks/results.js | 23 +++++++++++++++++++++++ 7 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 benchmarks/array.js create mode 100644 benchmarks/mean.js create mode 100644 benchmarks/measure.js create mode 100644 benchmarks/print.js create mode 100644 benchmarks/promise.js create mode 100644 benchmarks/results.js diff --git a/benchmarks/array.js b/benchmarks/array.js new file mode 100644 index 0000000..d1f936d --- /dev/null +++ b/benchmarks/array.js @@ -0,0 +1,7 @@ +export const getArray = function(length) { + return Array.from({ length }, getIndex) +} + +const getIndex = function(value, index) { + return index +} diff --git a/benchmarks/main.js b/benchmarks/main.js index 905e0b1..1baa4a8 100644 --- a/benchmarks/main.js +++ b/benchmarks/main.js @@ -1,13 +1,13 @@ import testCartesian from '../src/main.js' -const getIndex = function(value, index) { - return index -} - -const getArray = function(length) { - return new Array({ length }, getIndex) -} - -const DATA = [[getArray(5)], [getArray(10), getArray(10)]] - -console.log(testCartesian(DATA[1])) +import { printResults } from './print.js' +import { getArray } from './array.js' + +printResults( + [ + { variant: 'simple', args: [getArray(5)] }, + { variant: 'complex', args: [getArray(100), getArray(100)] }, + ], + [{ name: 'test-cartesian', func: testCartesian }], + { count: 1e4 }, +) diff --git a/benchmarks/mean.js b/benchmarks/mean.js new file mode 100644 index 0000000..e91f55c --- /dev/null +++ b/benchmarks/mean.js @@ -0,0 +1,12 @@ +// Calculate the mean of an array of integers +export const mean = function(array) { + return sum(array) / array.length +} + +const sum = function(array) { + return array.reduce(add, 0) +} + +const add = function(memo, number) { + return memo + number +} diff --git a/benchmarks/measure.js b/benchmarks/measure.js new file mode 100644 index 0000000..c87049d --- /dev/null +++ b/benchmarks/measure.js @@ -0,0 +1,13 @@ +import { performance } from 'perf_hooks' + +import { promiseThen } from './promise.js' + +// Measure how long a sync or async function take to execute +export const measure = function(func) { + const start = performance.now() + return promiseThen(func(), () => { + const end = performance.now() + const duration = end - start + return duration + }) +} diff --git a/benchmarks/print.js b/benchmarks/print.js new file mode 100644 index 0000000..57ae729 --- /dev/null +++ b/benchmarks/print.js @@ -0,0 +1,15 @@ +import { getResults } from './results.js' + +export const printResults = function(variants, funcs, { count }) { + const results = getResults(variants, funcs, { count }) + results.forEach(printResult) +} + +const printResult = function({ variant, name, duration }) { + // eslint-disable-next-line no-console, no-restricted-globals + console.log( + `${variant} ${name}: ${Math.round(duration * MICROSECS_TO_NANOSECS)}ns`, + ) +} + +const MICROSECS_TO_NANOSECS = 1e3 diff --git a/benchmarks/promise.js b/benchmarks/promise.js new file mode 100644 index 0000000..4e6b0e8 --- /dev/null +++ b/benchmarks/promise.js @@ -0,0 +1,18 @@ +// Like `promise.then()` except if `value` is not a promise +export const promiseThen = function(value, func) { + if (isPromise(value)) { + // eslint-disable-next-line promise/prefer-await-to-then + return value.then(func) + } + + return func() +} + +const isPromise = function(value) { + return ( + typeof value === 'object' && + value !== null && + // eslint-disable-next-line promise/prefer-await-to-then + typeof value.then === 'function' + ) +} diff --git a/benchmarks/results.js b/benchmarks/results.js new file mode 100644 index 0000000..2ea60bf --- /dev/null +++ b/benchmarks/results.js @@ -0,0 +1,23 @@ +import { getArray } from './array.js' +import { measure } from './measure.js' +import { mean } from './mean.js' + +export const getResults = function(variants, funcs, { count }) { + const countA = getArray(count) + return variants.flatMap(({ variant, args }) => + getVariantResult({ variant, args, funcs, count: countA }), + ) +} + +const getVariantResult = function({ variant, args, funcs, count }) { + return funcs.map(({ name, func }) => + getResult({ variant, args, name, func, count }), + ) +} + +const getResult = function({ variant, args, name, func, count }) { + const funcA = func.bind(null, ...args) + const durations = count.map(() => measure(funcA)) + const duration = mean(durations) + return { variant, name, duration, durations, count } +}