Skip to content
This repository was archived by the owner on Sep 30, 2023. It is now read-only.

Commit 8f82539

Browse files
committed
feat: save/compare results to/from file
1 parent cfd5d6e commit 8f82539

File tree

9 files changed

+155
-13
lines changed

9 files changed

+155
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
.nyc_output
3+
test/tmp

package-lock.json

Lines changed: 31 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"license": "MIT",
1414
"dependencies": {
1515
"expose-gc": "^1.0.0",
16+
"fs-extra": "^9.1.0",
1617
"yargs": "^15.4.1"
1718
},
1819
"localMaintainers": [

src/cli.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ const argv = yargs
99
.version(false)
1010
.help('help').alias('help', 'h')
1111
.options({
12+
save: {
13+
alias: 's',
14+
description: 'Save results to file',
15+
requiresArg: true,
16+
required: false,
17+
},
18+
compare: {
19+
alias: 'c',
20+
description: 'Compare results to file',
21+
requiresArg: true,
22+
required: false,
23+
},
1224
baseline: {
1325
alias: 'b',
1426
description: 'Run baseline benchmarks only',

src/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ require('expose-gc')
22
global.gc()
33

44
const os = require('os')
5+
const fs = require('fs-extra')
56

67
const report = require('./report')
78

@@ -52,8 +53,14 @@ const start = async (benchmarks, argv) => {
5253
output += ` in ${(runnerElapsed / 1000000000).toFixed(2)} seconds`
5354
process.stdout.write(output)
5455

56+
if (argv.save) {
57+
fs.ensureFileSync(argv.save)
58+
fs.writeJsonSync(argv.save, results, { spaces: 2 })
59+
}
60+
5561
if (argv.report) {
56-
report(results)
62+
const compare = argv.compare ? fs.readJsonSync(argv.compare) : undefined
63+
report(results, compare)
5764
}
5865
} catch (e) {
5966
console.log(e)

src/report.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const padStr = (str, max) => {
99
return str + repeatStr(' ', length)
1010
}
1111

12-
const reporter = (results) => {
12+
const reporter = (results, compare = []) => {
1313
const reports = [{
1414
name: 'Benchmark Name',
1515
ops: 'Ops / ms',
@@ -22,34 +22,51 @@ const reporter = (results) => {
2222
let maxMemWidth = reports[0].mem.length
2323

2424
for (const benchmark of results) {
25+
const savedBenchmark = compare.find(c => c.name === benchmark.name)
26+
2527
const nameWidth = benchmark.name.length
2628
if (maxNameWidth < nameWidth) {
2729
maxNameWidth = nameWidth
2830
}
2931

30-
const totalMs = (benchmark.elapsed / 1000000).toFixed(4)
31-
const opsPerMs = (benchmark.stats.count / totalMs).toFixed(4)
32-
const memUsed = benchmark.memory.after.heapUsed - benchmark.memory.before.heapUsed
33-
const memUsedMb = (memUsed / 1024 / 1024).toFixed(2)
32+
const getCalculations = (b) => {
33+
const totalMs = (b.elapsed / 1000000).toFixed(4)
34+
const opsPerMs = (b.stats.count / totalMs).toFixed(4)
35+
const memUsed = b.memory.after.heapUsed - b.memory.before.heapUsed
36+
const memUsedMb = (memUsed / 1024 / 1024).toFixed(2)
37+
return { totalMs, opsPerMs, memUsed, memUsedMb }
38+
}
39+
40+
const calculations = getCalculations(benchmark)
41+
const savedCalculations = savedBenchmark ? getCalculations(savedBenchmark) : undefined
42+
const getOutput = (type) => {
43+
const delta = savedCalculations ? (calculations[type] - savedCalculations[type]).toFixed(2) : 0
44+
return delta ? `${calculations[type]} (${delta})` : calculations[type]
45+
}
3446

35-
const opsWidth = opsPerMs.toString().length
47+
const ops = getOutput('opsPerMs')
48+
const opsWidth = ops.toString().length
3649
if (maxOpsWidth < opsWidth) {
3750
maxOpsWidth = opsWidth
3851
}
52+
53+
const totalMs = getOutput('totalMs')
3954
const totalWidth = totalMs.toString().length
4055
if (maxTotalWidth < totalWidth) {
4156
maxTotalWidth = totalWidth
4257
}
43-
const memWidth = memUsedMb.toString().length
58+
59+
const mem = getOutput('memUsedMb')
60+
const memWidth = mem.toString().length
4461
if (maxMemWidth < memWidth) {
4562
maxMemWidth = memWidth
4663
}
4764

4865
reports.push({
4966
name: benchmark.name,
50-
ops: opsPerMs,
51-
totalMs: totalMs,
52-
mem: memUsedMb
67+
ops,
68+
totalMs,
69+
mem
5370
})
5471
}
5572

test/cli.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('CLI Test', () => {
2424
expect(output).to.contain('stressLimit')
2525
expect(output).to.contain('baselineLimit')
2626
expect(output).to.contain('logLimit')
27+
expect(output).to.contain('save')
28+
expect(output).to.contain('compare')
2729
})
2830

2931
describe('baseline', () => {
@@ -270,4 +272,5 @@ describe('CLI Test', () => {
270272
await start(benchmarks, yargsResult)
271273
})
272274
})
275+
273276
})

test/compare.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* eslint-disable no-unused-expressions */
2+
3+
const yargs = require('yargs')
4+
const path = require('path')
5+
const fs = require('fs-extra')
6+
const cli = require('../src/cli')
7+
const expect = require('chai').expect
8+
const { start } = require('../src/index')
9+
10+
const benchmarks = require(process.cwd() + '/test/benchmarks')
11+
12+
describe('CLI Compare', function () {
13+
this.timeout(6000)
14+
15+
it('should compare results to file', async () => {
16+
const yargsCmd = yargs.command(cli)
17+
const tmpFile = path.join(__dirname, 'tmp/benchmark.json')
18+
const yargsResult1 = yargsCmd.parse(
19+
`cli --baseline -s ${tmpFile}`, {}
20+
)
21+
22+
await start(benchmarks, yargsResult1)
23+
24+
const yargsResult2 = yargsCmd.parse(
25+
`cli --baseline -r -c ${tmpFile}`, {}
26+
)
27+
await start(benchmarks, yargsResult2)
28+
29+
// TODO - test reporter output
30+
})
31+
})

test/save.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* eslint-disable no-unused-expressions */
2+
3+
const yargs = require('yargs')
4+
const path = require('path')
5+
const fs = require('fs-extra')
6+
const cli = require('../src/cli')
7+
const expect = require('chai').expect
8+
const { start } = require('../src/index')
9+
10+
const benchmarks = require(process.cwd() + '/test/benchmarks')
11+
12+
describe('CLI Save', function () {
13+
this.timeout(6000)
14+
15+
it('should save results to file', async () => {
16+
const yargsCmd = yargs.command(cli)
17+
const tmpFile = path.join(__dirname, 'tmp/benchmark.json')
18+
const yargsResult = yargsCmd.parse(
19+
`cli --baseline -s ${tmpFile}`, {}
20+
)
21+
22+
await start(benchmarks, yargsResult)
23+
24+
const results = fs.readJsonSync(tmpFile)
25+
expect(results).to.be.an('array')
26+
expect(results.length).to.be.equal(1)
27+
28+
const benchmark = results[0]
29+
expect(benchmark).to.have.property('name')
30+
expect(benchmark).to.have.property('cpus')
31+
expect(benchmark).to.have.property('loadavg')
32+
expect(benchmark).to.have.property('elapsed')
33+
expect(benchmark).to.have.property('stats')
34+
expect(benchmark).to.have.property('memory')
35+
36+
expect(benchmark.name).to.be.equal('console-baseline')
37+
expect(benchmark.memory).to.have.property('before')
38+
expect(benchmark.memory).to.have.property('after')
39+
expect(benchmark.stats).to.have.property('count')
40+
})
41+
})

0 commit comments

Comments
 (0)