Skip to content

Instantly share code, notes, and snippets.

@wilkmaia
Last active April 12, 2022 14:38
Show Gist options
  • Save wilkmaia/c2a43a145fcd0f9dda06710933c26850 to your computer and use it in GitHub Desktop.
Save wilkmaia/c2a43a145fcd0f9dda06710933c26850 to your computer and use it in GitHub Desktop.
Benchmark scripts
const os = require('os')
const fs = require('fs')
const path = require('path')
const Piscina = require('piscina')
const cliProgress = require('cli-progress')
// Worker threads setup
const piscina = new Piscina({
filename: path.resolve(__dirname, 'worker.js'),
maxThreads: 4 * os.cpus().length,
})
/**
* Beginning of Setup
*
* Check the variables below and adjust them as needed
*/
// CSV output file name
const outputFileName = './results.csv'
// For mult step, min and max range values and step
const minElementsMul = 1
const maxElementsMul = Math.pow(2, 20)
const multStep = 2
// For sum step, min and max range values and step
const minElementsSum = 5000
const maxElementsSum = 33000
const step = 500
// Number of attempts to average per step
const nElementReps = 30
/**
* End of Setup
*/
const minElements = minElementsMul
const maxElements = maxElementsMul
const f = fs.createWriteStream(outputFileName)
// Returns a sample element in the format of the issue's data
function makeSampleElements(__max) {
const maxNumber = 9999999999
const res = new Array(__max)
for (let i = 0; i < __max; ++i) {
res[i] = [Math.random() * maxNumber, null, null, null, null, null, null, null]
}
return res
}
// Returns an iterator for ranging over an interval that steps by
// summing or multiplying over a set step value. `start` and `stop`
// are inclusive
function* range(start, stop, step = 1, type = 'sum') {
if (stop === null) {
stop = start
start = 0
}
for (
let i = start;
step > 0 ? i <= stop : i >= stop;
type === 'mult' ? i *= step : i += step
) {
yield i
}
}
// Process an individual data entry `nElementReps` times and returns the
// accumulated processing time
const processEntry = async (data) => {
let t1 = 0
let t2 = 0
for await (let _ of range(0, nElementReps - 1)) {
const [_t1, _t2] = await piscina.run(data)
t1 += _t1
t2 += _t2
}
return [t1, t2]
}
// Benchmark runner
const run = async () => {
f.write('array_size,json_stringify_ns,fjs_stringify_ns,ratio\n')
const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
// For ranges with sum step
// progressBar.start((maxElements - minElements) / step, 0)
// const __range = range(minElements, maxElements, step, 'sum')
// For ranges with mult step
progressBar.start(Math.log2(maxElements / minElements), 0)
const __range = range(minElements, maxElements, multStep, 'mult')
const res = {}
await Promise.all([...__range].map(async (i) => {
// Since the range is iterated over in parallel we need to set up a new
// array for each run
const data = { series: [] }
data.series = makeSampleElements(i)
res[i] = await processEntry(data, i)
progressBar.update(Object.keys(res).length)
}))
progressBar.stop()
console.log('Writing results!')
for (let i in res) {
const [t1, t2] = res[i]
f.write(`${i},${t1/nElementReps},${t2/nElementReps},${t2/t1}\n`, 'utf-8')
}
f.close()
}
run()
{
"dependencies": {
"cli-progress": "^3.10.0",
"piscina": "^3.2.0"
}
}
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "response",
"type": "object",
"additionalProperties": false,
"required": [
"series"
],
"properties": {
"series": {
"$id": "#/properties/series",
"type": "array",
"items": {
"$id": "#/properties/series/items",
"type": "array",
"minItems": 2,
"items": {
"$id": "#/properties/series/items/items",
"type": [
"number",
"boolean",
"string",
"null"
],
"minLength": 1
}
}
}
}
}
const Piscina = require('piscina')
const FJS = require('.')
const schema = require('./schema.json')
const stringify = FJS(schema)
module.exports = async (data) => {
let t = process.hrtime()
JSON.stringify(data)
let [s, ns] = process.hrtime(t)
t = process.hrtime()
stringify(data)
let [s2, ns2] = process.hrtime(t)
const json_stringify_ns = s * 1e9 + ns
const fjs_stringify_ns = s2 * 1e9 + ns2
return [json_stringify_ns, fjs_stringify_ns]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment