Skip to content

Commit

Permalink
docs: Update benchmark with Papr v14 and node.js v18 (#540)
Browse files Browse the repository at this point in the history
  • Loading branch information
avaly authored Aug 17, 2023
1 parent cf5070f commit d23d1d2
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 411 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docs/data.json linguist-generated=true
42 changes: 42 additions & 0 deletions .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Benchmark

on:
schedule:
- cron: '30 5 * * *'

jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- uses: pnpm/[email protected]
with:
version: 8
- uses: actions/[email protected]
with:
node-version-file: 'package.json'
cache: 'pnpm'
- uses: supercharge/[email protected]
with:
mongodb-version: 6.0
- id: date
run: |
echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT
- run: node -v
- run: pnpm install --frozen-lockfile
- run: pnpm benchmark
- id: create-pr
uses: peter-evans/create-pull-request@v5
with:
add-paths: docs/data.json
base: main
body: 'Automated benchmark results generated on ${{ steps.date.outputs.date }}'
branch: docs/benchmark-${{ steps.date.outputs.date }}
commit-message: 'docs: Benchmark results ${{ steps.date.outputs.date }}'
delete-branch: true
reviewers: avaly
title: 'docs: Benchmark results ${{ steps.date.outputs.date }}'
- if: ${{ steps.create-pr.outputs.pull-request-number }}
run: |
echo "Pull Request Number - ${{ steps.create-pr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.create-pr.outputs.pull-request-url }}"
7 changes: 0 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ jobs:
with:
node-version: ${{ matrix.node }}
cache: 'pnpm'
- uses: actions/[email protected]
with:
path: |
node_modules
key: node-${{ matrix.node }}-${{ hashFiles('package.json', 'pnpm-lock.yaml') }}
restore-keys: |
node-${{ matrix.node }}-
- run: node -v
- run: pnpm install --frozen-lockfile
- run: pnpm test:build
Expand Down
144 changes: 116 additions & 28 deletions benchmark/run.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import fs from 'fs';
import barChart from '@byu-oit/bar-chart';
import { ObjectId, Decimal128 } from 'mongodb';
import mongoose from 'mongoose';
import SampleMongoose from './mongoose.js';
import SamplePapr from './papr.js';
import setup, { db, teardown } from './setup.js';

const CHART_LABELS = ['insert', 'find', 'update'];
const CHART_LEGEND_LABELS = ['mongodb', 'papr', 'mongoose'];
const INSERT_COUNT = 10000;
const FIND_COUNT = 10000;
const UPDATE_COUNT = 10000;
Expand All @@ -34,6 +31,12 @@ const TIMES = {
},
};
const NS_PER_S = 1e9;
const RESULTS = [];

function printResult(line) {
RESULTS.push(line);
console.log(line);
}

function timer() {
const start = process.hrtime.bigint();
Expand All @@ -49,10 +52,12 @@ function random(max) {
return Math.floor(Math.random() * max);
}

function randomDecimal(max) {
function randomDecimal(max, type) {
const cents = random(99);
const dollars = random(max);
return Decimal128(`${dollars}.${cents}`);
return type === 'mongoose'
? new mongoose.Types.Decimal128(`${dollars}.${cents}`)
: new Decimal128(`${dollars}.${cents}`);
}

function randomURL() {
Expand All @@ -75,7 +80,7 @@ function randomDocument(source, type) {
{ score: random(10) },
{ score: random(10) },
],
salary: randomDecimal(100000),
salary: randomDecimal(100000, type),
scores: [random(100), random(100)],
...(source && { source }),
url: randomURL(),
Expand Down Expand Up @@ -109,9 +114,9 @@ async function test(library, name, operations, action) {
const time = testTimer();
const ops = (operations / time).toFixed(2);

TIMES[library][name] = ops;
TIMES[library][name] = operations / time;

console.log(`${library}.${name} ~ ${ops} ops/sec`);
printResult(`${library}.${name} ~ ${ops} ops/sec`);
}

async function run() {
Expand All @@ -130,7 +135,7 @@ async function run() {
IDS.mongoose.push(doc._id);
});

console.log('---');
printResult('---');

await test('mongodb', 'find', FIND_COUNT, async () => {
await mongodb.find(randomQueryList('mongodb')).toArray();
Expand All @@ -142,7 +147,7 @@ async function run() {
await SampleMongoose.find(randomQueryList('mongoose'));
});

console.log('---');
printResult('---');

await test('mongodb', 'update', UPDATE_COUNT, async () => {
await mongodb.updateOne(randomQueryID('mongodb'), { $set: { age: random(100) } });
Expand All @@ -153,27 +158,110 @@ async function run() {
await test('mongoose', 'update', UPDATE_COUNT, async () => {
await SampleMongoose.updateOne(randomQueryID('mongoose'), { age: random(100) });
});
}

const chart = barChart({
colors: ['#13aa52', '#e5a00d', '#800'],
data: [
[TIMES.mongodb.insert, TIMES.papr.insert, TIMES.mongoose.insert],
[TIMES.mongodb.find, TIMES.papr.find, TIMES.mongoose.find],
[TIMES.mongodb.update, TIMES.papr.update, TIMES.mongoose.update],
],
labels: CHART_LABELS,
legendLabels: CHART_LEGEND_LABELS,
})
.replace('<rect x="0" y="0" width="100" height="60" fill="url(#bgGradient)" />', '')
.replace('stroke: #ccc;', 'stroke: #555;')
.replace(
'font-family: "Helvetica Nue", Arial, sans-serif;',
'font-family: "Helvetica Nue", Arial, sans-serif; fill: #fff;'
);

fs.writeFileSync('docs/benchmark.svg', chart);
async function save() {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));

const data = {
benchmark: {
charts: {
find: JSON.stringify({
caption: 'Operations per second',
data: [
{
colour: '#13aa52',
label: 'mongodb',
value: TIMES.mongodb.find,
},
{
colour: '#e5a00d',
label: 'papr',
value: TIMES.papr.find,
},
{
colour: '#800',
label: 'mongoose',
value: TIMES.mongoose.find,
},
],
options: {
labels: true,
},
title: 'Finds',
type: 'review',
}),
insert: JSON.stringify({
caption: 'Operations per second',
data: [
{
colour: '#13aa52',
label: 'mongodb',
value: TIMES.mongodb.insert,
},
{
colour: '#e5a00d',
label: 'papr',
value: TIMES.papr.insert,
},
{
colour: '#800',
label: 'mongoose',
value: TIMES.mongoose.insert,
},
],
options: {
labels: true,
},
title: 'Inserts',
type: 'review',
}),
update: JSON.stringify({
caption: 'Operations per second',
data: [
{
colour: '#13aa52',
label: 'mongodb',
value: TIMES.mongodb.update,
},
{
colour: '#e5a00d',
label: 'papr',
value: TIMES.papr.update,
},
{
colour: '#800',
label: 'mongoose',
value: TIMES.mongoose.update,
},
],
options: {
labels: true,
},
title: 'Updates',
type: 'review',
}),
},
configuration: [
`- node.js ${process.version}`,
`- mongodb v${pkg.devDependencies.mongodb}`,
`- papr v${pkg.version}`,
`- mongoose v${pkg.devDependencies.mongoose}`,
'- MongoDB server v6.0',
].join('\n'),
date: new Date().toLocaleDateString('en-US', {
day: 'numeric',
month: 'long',
year: 'numeric',
}),
results: RESULTS.join('\n'),
},
};

fs.writeFileSync('docs/data.json', JSON.stringify(data, null, 2));
}

await setup();
await run();
await save();
await teardown();
32 changes: 13 additions & 19 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,25 @@ The JSON Schema validation feature is available in MongoDB server since version

Due to its bare feature set and validation run in the MongoDB server, Papr is _fast_.

```charty
{{&benchmark.charts.insert}}
```
mongodb.insert ~ 748.81 ops/sec
papr.insert ~ 711.09 ops/sec
mongoose.insert ~ 530.22 ops/sec
---
mongodb.find ~ 598.82 ops/sec
papr.find ~ 589.31 ops/sec
mongoose.find ~ 478.46 ops/sec
---
mongodb.update ~ 755.38 ops/sec
papr.update ~ 696.47 ops/sec
mongoose.update ~ 598.28 ops/sec

```charty
{{&benchmark.charts.find}}
```

![](benchmark.svg)
```charty
{{&benchmark.charts.update}}
```

The chart represents operations per second.
```
{{&benchmark.results}}
```

The benchmark numbers are from a benchmark with:
The benchmark results are generated on {{benchmark.date}} from a benchmark with:

- Node.js 14.19.3
- MongoDB server v5.0.2
- `mongodb` v4.6.0
- `papr` v4.0.0
- `mongoose` v6.3.5
{{benchmark.configuration}}

This benchmark can be run locally with `pnpm benchmark`. Run `pnpm benchmark --help` for more information on available arguments.

Expand Down
78 changes: 0 additions & 78 deletions docs/benchmark.svg

This file was deleted.

Loading

0 comments on commit d23d1d2

Please sign in to comment.