diff options
Diffstat (limited to 'fastify-busboy/benchmarks')
15 files changed, 409 insertions, 0 deletions
diff --git a/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_12.json b/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_12.json new file mode 100644 index 0000000..69468dd --- /dev/null +++ b/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_12.json @@ -0,0 +1,10 @@ +{ + "runtimeVersion": "12.22.7, V8 7.8.279.23-node.56", + "benchmarkName": "Busboy comparison", + "benchmarkEntryName": "busboy", + "benchmarkCycles": 10, + "benchmarkCycleSamples": 50, + "warmupCycles": 10, + "meanTimeNs": 1945927.3472222222, + "meanTimeMs": 1.9459273472222223 +}
\ No newline at end of file diff --git a/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_16.json b/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_16.json new file mode 100644 index 0000000..b4c492a --- /dev/null +++ b/fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_16.json @@ -0,0 +1,10 @@ +{ + "runtimeVersion": "16.13.0, V8 9.4.146.19-node.13", + "benchmarkName": "Busboy comparison", + "benchmarkEntryName": "busboy", + "benchmarkCycles": 2000, + "benchmarkCycleSamples": 50, + "warmupCycles": 1000, + "meanTimeNs": 340114.0411908194, + "meanTimeMs": 0.3401140411908194 +}
\ No newline at end of file diff --git a/fastify-busboy/benchmarks/_results/Busboy_comparison-fastify-busboy-Node_16.json b/fastify-busboy/benchmarks/_results/Busboy_comparison-fastify-busboy-Node_16.json new file mode 100644 index 0000000..30f5d1e --- /dev/null +++ b/fastify-busboy/benchmarks/_results/Busboy_comparison-fastify-busboy-Node_16.json @@ -0,0 +1,10 @@ +{ + "runtimeVersion": "16.13.0, V8 9.4.146.19-node.13", + "benchmarkName": "Busboy comparison", + "benchmarkEntryName": "fastify-busboy", + "benchmarkCycles": 2000, + "benchmarkCycleSamples": 50, + "warmupCycles": 1000, + "meanTimeNs": 270984.48082281026, + "meanTimeMs": 0.27098448082281024 +}
\ No newline at end of file diff --git a/fastify-busboy/benchmarks/busboy/contestants/busboy.js b/fastify-busboy/benchmarks/busboy/contestants/busboy.js new file mode 100644 index 0000000..6cb3414 --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/contestants/busboy.js @@ -0,0 +1,40 @@ +'use strict' + +const Busboy = require('busboy') +const { buffer, boundary } = require('../data') + +function process () { + const busboy = Busboy({ + headers: { + 'content-type': 'multipart/form-data; boundary=' + boundary + } + }) + let processedData = '' + + return new Promise((resolve, reject) => { + busboy.on('file', (field, file, filename, encoding, mimetype) => { + // console.log('read file') + file.on('data', (data) => { + processedData += data.toString() + // console.log(`File [${filename}] got ${data.length} bytes`); + }) + file.on('end', (fieldname) => { + // console.log(`File [${fieldname}] Finished`); + }) + }) + + busboy.on('error', function (err) { + reject(err) + }) + busboy.on('finish', function () { + resolve(processedData) + }) + busboy.write(buffer, () => { }) + + busboy.end() + }) +} + +module.exports = { + process +} diff --git a/fastify-busboy/benchmarks/busboy/contestants/fastify-busboy.js b/fastify-busboy/benchmarks/busboy/contestants/fastify-busboy.js new file mode 100644 index 0000000..6750f77 --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/contestants/fastify-busboy.js @@ -0,0 +1,41 @@ +'use strict' + +const Busboy = require('../../../lib/main') +const { buffer, boundary } = require('../data') + +function process () { + const busboy = new Busboy({ + headers: { + 'content-type': 'multipart/form-data; boundary=' + boundary + } + }) + + let processedData = '' + + return new Promise((resolve, reject) => { + busboy.on('file', (field, file, filename, encoding, mimetype) => { + // console.log('read file') + file.on('data', (data) => { + processedData += data.toString() + // console.log(`File [${filename}] got ${data.length} bytes`); + }) + file.on('end', (fieldname) => { + // console.log(`File [${fieldname}] Finished`); + }) + }) + + busboy.on('error', function (err) { + reject(err) + }) + busboy.on('finish', function () { + resolve(processedData) + }) + busboy.write(buffer, () => { }) + + busboy.end() + }) +} + +module.exports = { + process +} diff --git a/fastify-busboy/benchmarks/busboy/data.js b/fastify-busboy/benchmarks/busboy/data.js new file mode 100644 index 0000000..4fdefae --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/data.js @@ -0,0 +1,34 @@ +'use strict'
+
+const boundary = '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k'
+const randomContent = Buffer.from(makeString(1024 * 500), 'utf8')
+const buffer = createMultipartBuffer(boundary)
+
+function makeString (length) {
+ let result = ''
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
+ const charactersLength = characters.length
+ for (var i = 0; i < length; i++) { // eslint-disable-line no-var
+ result += characters.charAt(Math.floor(Math.random() *
+ charactersLength))
+ }
+ return result
+}
+
+function createMultipartBuffer (boundary) {
+ const payload = [
+ '--' + boundary,
+ 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
+ 'Content-Type: application/octet-stream',
+ '',
+ randomContent,
+ '--' + boundary + '--'
+ ].join('\r\n')
+ return Buffer.from(payload, 'ascii')
+}
+
+module.exports = {
+ boundary,
+ buffer,
+ randomContent
+}
diff --git a/fastify-busboy/benchmarks/busboy/executioner.js b/fastify-busboy/benchmarks/busboy/executioner.js new file mode 100644 index 0000000..524912c --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/executioner.js @@ -0,0 +1,50 @@ +'use strict' + +const { process: processBusboy } = require('./contestants/busboy') +const { process: processFastify } = require('./contestants/fastify-busboy') +const { getCommonBuilder } = require('../common/commonBuilder') +const { validateAccuracy } = require('./validator') +const { resolveContestant } = require('../common/contestantResolver') +const { outputResults } = require('../common/resultUtils') + +const contestants = { + busboy: measureBusboy, + fastify: measureFastify +} + +async function measureBusboy () { + const benchmark = getCommonBuilder() + .benchmarkName('Busboy comparison') + .benchmarkEntryName('busboy') + .asyncFunctionUnderTest(processBusboy) + .build() + const benchmarkResults = await benchmark.executeAsync() + outputResults(benchmark, benchmarkResults) +} + +async function measureFastify () { + const benchmark = getCommonBuilder() + .benchmarkName('Busboy comparison') + .benchmarkEntryName('fastify-busboy') + .asyncFunctionUnderTest(processFastify) + .build() + const benchmarkResults = await benchmark.executeAsync() + outputResults(benchmark, benchmarkResults) +} + +function execute () { + return validateAccuracy(processBusboy()) + .then(() => { + return validateAccuracy(processFastify()) + }) + .then(() => { + const contestant = resolveContestant(contestants) + return contestant() + }).then(() => { + console.log('all done') + }).catch((err) => { + console.error(`Something went wrong: ${err.message}`) + }) +} + +execute() diff --git a/fastify-busboy/benchmarks/busboy/regenerate.cmd b/fastify-busboy/benchmarks/busboy/regenerate.cmd new file mode 100644 index 0000000..87c0768 --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/regenerate.cmd @@ -0,0 +1,17 @@ +rem Make sure to run this in Admin account
+rem
+call npm run install-node
+timeout /t 2
+call nvm use 17.2.0
+timeout /t 2
+call npm run benchmark-all
+call nvm use 16.13.1
+timeout /t 2
+call npm run benchmark-all
+call nvm use 14.18.2
+timeout /t 2
+call npm run benchmark-all
+call nvm use 12.22.7
+timeout /t 2
+call npm run benchmark-all
+call npm run combine-results
diff --git a/fastify-busboy/benchmarks/busboy/validator.js b/fastify-busboy/benchmarks/busboy/validator.js new file mode 100644 index 0000000..a86cc33 --- /dev/null +++ b/fastify-busboy/benchmarks/busboy/validator.js @@ -0,0 +1,15 @@ +'use strict'
+
+const { validateEqual } = require('validation-utils')
+const { randomContent } = require('./data')
+
+const EXPECTED_RESULT = randomContent.toString()
+
+async function validateAccuracy (actualResultPromise) {
+ const result = await actualResultPromise
+ validateEqual(result, EXPECTED_RESULT)
+}
+
+module.exports = {
+ validateAccuracy
+}
diff --git a/fastify-busboy/benchmarks/common/commonBuilder.js b/fastify-busboy/benchmarks/common/commonBuilder.js new file mode 100644 index 0000000..b5707aa --- /dev/null +++ b/fastify-busboy/benchmarks/common/commonBuilder.js @@ -0,0 +1,46 @@ +'use strict' + +const { validateNotNil } = require('validation-utils') +const { BenchmarkBuilder } = require('photofinish') +const getopts = require('getopts') + +const options = getopts(process.argv.slice(1), { + alias: { + preset: 'p' + }, + default: {} +}) + +const PRESET = { + LOW: (builder) => { + return builder + .warmupCycles(1000) + .benchmarkCycles(1000) + }, + + MEDIUM: (builder) => { + return builder + .warmupCycles(1000) + .benchmarkCycles(2000) + }, + + HIGH: (builder) => { + return builder + .warmupCycles(1000) + .benchmarkCycles(10000) + } +} + +function getCommonBuilder () { + const presetId = options.preset || 'MEDIUM' + const preset = validateNotNil(PRESET[presetId.toUpperCase()], `Unknown preset: ${presetId}`) + + const builder = new BenchmarkBuilder() + preset(builder) + return builder + .benchmarkCycleSamples(50) +} + +module.exports = { + getCommonBuilder +} diff --git a/fastify-busboy/benchmarks/common/contestantResolver.js b/fastify-busboy/benchmarks/common/contestantResolver.js new file mode 100644 index 0000000..7cfc90e --- /dev/null +++ b/fastify-busboy/benchmarks/common/contestantResolver.js @@ -0,0 +1,26 @@ +'use strict'
+
+const getopts = require('getopts')
+
+const options = getopts(process.argv.slice(1), {
+ alias: {
+ contestant: 'c'
+ },
+ default: {}
+})
+
+function resolveContestant (contestants) {
+ const contestantId = options.contestant
+ const contestant = Number.isFinite(contestantId)
+ ? Object.values(contestants)[contestantId]
+ : contestants[contestantId]
+
+ if (!contestant) {
+ throw new Error(`Unknown contestant ${contestantId}`)
+ }
+ return contestant
+}
+
+module.exports = {
+ resolveContestant
+}
diff --git a/fastify-busboy/benchmarks/common/executionUtils.js b/fastify-busboy/benchmarks/common/executionUtils.js new file mode 100644 index 0000000..8c52ec8 --- /dev/null +++ b/fastify-busboy/benchmarks/common/executionUtils.js @@ -0,0 +1,18 @@ +'use strict'
+
+const { getCommonBuilder } = require('./commonBuilder')
+const { outputResults } = require('./resultUtils')
+
+function getMeasureFn (constestandId, fn) {
+ return () => {
+ const benchmark = getCommonBuilder()
+ .benchmarkEntryName(constestandId)
+ .functionUnderTest(fn).build()
+ const benchmarkResults = benchmark.execute()
+ outputResults(benchmark, benchmarkResults)
+ }
+}
+
+module.exports = {
+ getMeasureFn
+}
diff --git a/fastify-busboy/benchmarks/common/resultUtils.js b/fastify-busboy/benchmarks/common/resultUtils.js new file mode 100644 index 0000000..ec7bce7 --- /dev/null +++ b/fastify-busboy/benchmarks/common/resultUtils.js @@ -0,0 +1,17 @@ +'use strict' + +const { exportResults } = require('photofinish') + +function outputResults (benchmark, benchmarkResults) { + console.log( + `Mean time for ${ + benchmark.benchmarkEntryName + } is ${benchmarkResults.meanTime.getTimeInNanoSeconds()} nanoseconds` + ) + + exportResults(benchmarkResults, { exportPath: '_results' }) +} + +module.exports = { + outputResults +} diff --git a/fastify-busboy/benchmarks/common/resultsCombinator.js b/fastify-busboy/benchmarks/common/resultsCombinator.js new file mode 100644 index 0000000..253211b --- /dev/null +++ b/fastify-busboy/benchmarks/common/resultsCombinator.js @@ -0,0 +1,54 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const getopts = require('getopts') +const systemInformation = require('systeminformation') +const { loadResults } = require('photofinish') + +const options = getopts(process.argv.slice(1), { + alias: { + resultsDir: 'r', + precision: 'p' + }, + default: {} +}) + +const { generateTable } = require('photofinish') + +async function getSpecs () { + const cpuInfo = await systemInformation.cpu() + + return { + cpu: { + brand: cpuInfo.brand, + speed: `${cpuInfo.speed} GHz` + } + } +} + +async function saveTable () { + const baseResultsDir = options.resultsDir + const benchmarkResults = await loadResults(baseResultsDir) + + const table = generateTable(benchmarkResults, { + precision: options.precision, + sortBy: [ + { field: 'meanTimeNs', order: 'asc' } + ] + }) + + const specs = await getSpecs() + + console.log(specs) + console.log(table) + + const targetFilePath = path.resolve(baseResultsDir, 'results.md') + fs.writeFileSync( + targetFilePath, + `${table}` + + `\n\n**Specs**: ${specs.cpu.brand} (${specs.cpu.speed})` + ) +} + +saveTable() diff --git a/fastify-busboy/benchmarks/package.json b/fastify-busboy/benchmarks/package.json new file mode 100644 index 0000000..2574b8b --- /dev/null +++ b/fastify-busboy/benchmarks/package.json @@ -0,0 +1,21 @@ +{ + "name": "busboy-benchmarks", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "getopts": "^2.3.0", + "photofinish": "^1.8.0", + "systeminformation": "^5.9.15", + "tslib": "^2.3.1", + "validation-utils": "^7.0.0" + }, + "scripts": { + "install-node": "nvm install 17.2.0 && nvm install 16.13.1 && nvm install 14.18.2 && nvm install 12.22.7", + "benchmark-busboy": "node busboy/executioner.js -c 0", + "benchmark-fastify": "node busboy/executioner.js -c 1", + "benchmark-all": "npm run benchmark-busboy -- -p high && npm run benchmark-fastify -- -p high", + "benchmark-all-medium": "npm run benchmark-busboy -- -p medium && npm run benchmark-fastify -- -p medium", + "benchmark-all-low": "npm run benchmark-busboy -- -p low && npm run benchmark-fastify -- -p low", + "combine-results": "node common/resultsCombinator.js -r _results -p 6" + } +} |