summaryrefslogtreecommitdiffstats
path: root/fastify-busboy/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'fastify-busboy/benchmarks')
-rw-r--r--fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_12.json10
-rw-r--r--fastify-busboy/benchmarks/_results/Busboy_comparison-busboy-Node_16.json10
-rw-r--r--fastify-busboy/benchmarks/_results/Busboy_comparison-fastify-busboy-Node_16.json10
-rw-r--r--fastify-busboy/benchmarks/busboy/contestants/busboy.js40
-rw-r--r--fastify-busboy/benchmarks/busboy/contestants/fastify-busboy.js41
-rw-r--r--fastify-busboy/benchmarks/busboy/data.js34
-rw-r--r--fastify-busboy/benchmarks/busboy/executioner.js50
-rw-r--r--fastify-busboy/benchmarks/busboy/regenerate.cmd17
-rw-r--r--fastify-busboy/benchmarks/busboy/validator.js15
-rw-r--r--fastify-busboy/benchmarks/common/commonBuilder.js46
-rw-r--r--fastify-busboy/benchmarks/common/contestantResolver.js26
-rw-r--r--fastify-busboy/benchmarks/common/executionUtils.js18
-rw-r--r--fastify-busboy/benchmarks/common/resultUtils.js17
-rw-r--r--fastify-busboy/benchmarks/common/resultsCombinator.js54
-rw-r--r--fastify-busboy/benchmarks/package.json21
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"
+ }
+}