Skip to content

Commit

Permalink
chore: add benchmarking script, additional benchmarks (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
mweberxyz authored Feb 18, 2024
1 parent fea0b89 commit d5ef69b
Show file tree
Hide file tree
Showing 17 changed files with 210 additions and 17 deletions.
81 changes: 81 additions & 0 deletions benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict'

const { readdirSync } = require('fs')
const { spawn } = require('child_process')
const { promisify } = require('node:util')
const sget = promisify(require('simple-get').concat)
const autocannon = require('autocannon')
const delay = require('delay')
const { join } = require('node:path')

const benchmarkDir = join(__dirname, 'benchmark')

// Keep track of spawned processes and kill if runner killed
const processes = []

process.on('SIGINT', () => {
for (const p of processes) {
p.kill('SIGKILL')
}
process.exit()
})

;(async function () {
const benchmarkFiles = readdirSync(benchmarkDir)
// don't include setup file as a benchmark
.filter((fileName) => fileName !== 'setup.js')
// sort by filename length to ensure base benchmarks run first
.sort((a, b) => a.length - b.length)

for (const benchmarkFile of benchmarkFiles) {
let benchmarkProcess

try {
// Spawn benchmark process
benchmarkProcess = spawn('node', [benchmarkFile], {
detached: true,
cwd: benchmarkDir
})

processes.push(benchmarkProcess)

// wait for `server listening` from benchmark
await Promise.race([
new Promise((resolve) => {
const stdOutCb = (d) => {
if (d.toString().includes('server listening')) {
benchmarkProcess.stdout.removeListener('data', stdOutCb)
resolve()
}
}
benchmarkProcess.stdout.on('data', stdOutCb)
}),
delay(5000).then(() => Promise.reject(new Error('timed out waiting for server listening')))
])

// fire single initial request as warmup
await sget('http://localhost:3000/')

// run autocannon
const result = await autocannon({
url: 'http://localhost:3000/',
connections: 100,
duration: 5,
pipelining: 10
})
if (result.non2xx > 0) {
throw Object.assign(new Error('Some requests did not return 200'), {
statusCodeStats: result.statusCodeStats
})
}
console.log(`${benchmarkFile}: ${result.requests.average} req/s`)
} catch (err) {
console.error(`${benchmarkFile}:`, err)
} finally {
if (benchmarkProcess) {
benchmarkProcess.kill('SIGKILL')
processes.pop()
}
}
}
})()
6 changes: 6 additions & 0 deletions benchmark/fastify-art.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { 'art-template': require('art-template') },
route: (req, reply) => { reply.view('index.art', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-dot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { dot: require('dot') },
route: (req, reply) => { reply.view('testdot', { text: 'text' }) }
})
7 changes: 7 additions & 0 deletions benchmark/fastify-ejs-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('ejs-async.ejs', { text: 'text' }) },
options: { async: true }
})
9 changes: 9 additions & 0 deletions benchmark/fastify-ejs-global-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('index-for-layout.ejs', { text: 'text' }) },
pluginOptions: {
layout: 'layout.html'
}
})
6 changes: 6 additions & 0 deletions benchmark/fastify-ejs-local-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('index-for-layout.ejs', { text: 'text' }, { layout: 'layout.html' }) }
})
17 changes: 17 additions & 0 deletions benchmark/fastify-ejs-minify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict'

require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('index.ejs', { text: 'text' }) },
options: {
useHtmlMinifier: require('html-minifier'),
htmlMinifierOptions: {
removeComments: true,
removeCommentsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
}
}
})
9 changes: 9 additions & 0 deletions benchmark/fastify-eta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

const { Eta } = require('eta')
const eta = new Eta()

require('./setup.js')({
engine: { eta },
route: (req, reply) => { reply.view('index.eta', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-handlebars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { handlebars: require('handlebars') },
route: (req, reply) => { reply.view('index.html', { text: 'text' }) }
})
9 changes: 9 additions & 0 deletions benchmark/fastify-liquid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

const { Liquid } = require('liquidjs')
const liquid = new Liquid()

require('./setup.js')({
engine: { liquid },
route: (req, reply) => { reply.view('index.liquid', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-mustache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { mustache: require('mustache') },
route: (req, reply) => { reply.view('index.html', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-nunjucks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { nunjucks: require('nunjucks') },
route: (req, reply) => { reply.view('index.njk', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-pug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { pug: require('pug') },
route: (req, reply) => { reply.view('index.pug', { text: 'text' }) }
})
6 changes: 6 additions & 0 deletions benchmark/fastify-twig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

require('./setup.js')({
engine: { twig: require('twig') },
route: (req, reply) => { reply.view('index.twig', { title: 'fastify', text: 'text' }) }
})
20 changes: 3 additions & 17 deletions benchmark/fastify.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
'use strict'

process.env.NODE_ENV = 'production'

const fastify = require('fastify')()

fastify.register(require('../index'), {
engine: {
ejs: require('ejs')
}
})

fastify.get('/', (req, reply) => {
reply.view('../templates/index.ejs', { text: 'text' })
})

fastify.listen({ port: 3000 }, err => {
if (err) throw err
console.log(`server listening on ${fastify.server.address().port}`)
require('./setup.js')({
engine: { ejs: require('ejs') },
route: (req, reply) => { reply.view('index.ejs', { text: 'text' }) }
})
24 changes: 24 additions & 0 deletions benchmark/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

process.env.NODE_ENV = 'production'

const fastify = require('fastify')()
const path = require('node:path')

module.exports = function ({ engine, route, options = {}, pluginOptions }) {
fastify.register(require('../index'), {
engine,
options,
root: path.join(__dirname, '../templates'),
...pluginOptions
})

fastify.get('/', route)

fastify.listen({ port: 3000 }, err => {
if (err) throw err
console.log(`server listening on ${fastify.server.address().port}`)
})

return fastify
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "commonjs",
"types": "types/index.d.ts",
"scripts": {
"benchmark": "node benchmark.js",
"example": "node examples/example.js",
"example-with-options": "node examples/example-ejs-with-some-options.js",
"example-typescript": "npx ts-node types/index.test-d.ts",
Expand Down Expand Up @@ -46,7 +47,9 @@
"@fastify/pre-commit": "^2.0.2",
"@types/node": "^20.1.0",
"art-template": "^4.13.2",
"autocannon": "^7.15.0",
"cross-env": "^7.0.2",
"delay": "^5.0.0",
"dot": "^1.1.3",
"ejs": "^3.1.8",
"eta": "^3.0.3",
Expand Down

0 comments on commit d5ef69b

Please sign in to comment.