Skip to content

Instantly share code, notes, and snippets.

@rluvaton
Forked from perliedman/pouchdb-benchmark.js
Created February 7, 2019 16:10
Show Gist options
  • Save rluvaton/060a47b22c91ec127671d4dca9fcf6af to your computer and use it in GitHub Desktop.
Save rluvaton/060a47b22c91ec127671d4dca9fcf6af to your computer and use it in GitHub Desktop.
PouchDB Benchmark
var dbName = 'http://localhost:5984/couch-test',
nDocs = 10000,
batchSize = 1000,
scrapFactor = 0,
docs = [],
testQuery = 'entries/sumTime',
destroyDb = false,
_log = console.log,
db;
console.log = function() {
var e = document.getElementById('log'),
i;
for (i = 0; i < arguments.length; i++) {
e.innerHTML = e.innerHTML + arguments[i] + '\n';
}
_log.apply(console, arguments);
};
function setUp() {
db = new PouchDB({name:dbName});
}
function tearDown() {
if (destroyDb) {
db.destroy(function(err, info) {
if (err) {
console.log(err);
}
});
} else {
db.bulkDocs({docs: docs.map(function(d) { return {_id: d.id, _rev: d.rev, _deleted: true}; })});
}
}
function range(lo, hi) {
var r = [],
i;
for (i = lo; i < hi; i++) {
r.push(i);
}
return r;
}
function time(fn, times, sequential) {
var i,
start = Date.now(),
result;
function logStats() {
var t = Date.now() - start;
console.log(fn.name + ': ' + t + ' ms, ' + (t / times) + ' ms/run.');
}
if (!sequential){
result = new Promise(function(resolve, reject) {
Promise.all(range(0, times).map(fn)).
then(function() {
logStats();
resolve();
}, function(err) {
reject(err);
});
});
} else {
result = new Promise(function(resolve, reject) {
function next(i) {
if (i < times) {
fn(i).
then(function() { next(i + 1); }).
catch(reject);
} else {
logStats();
resolve();
}
}
next(0);
});
}
return result;
}
function createScrap(n) {
return Promise.all(range(0, Math.ceil(n / batchSize)).map(function(i) {
return db.bulkDocs({
docs: range(i * batchSize, Math.min((i + 1) * batchSize, n)).map(function(j) {
return {
type: 'scrap',
data: j
};
})
});
}));
}
function createDocuments(i) {
var activities = [
'Planering', 'Möte', 'Sprängning', 'Grävarbete',
'Transport'
],
projects = [
'Lilla Torget', 'Västlänken', 'Kruthusgatan'
],
customers = [
'Skanska', 'Sweco', 'ÅF', 'Privat'
],
descriptions = [
'', '', '', 'Kunden galen', 'Grus i maskineriet', 'OBS! Fakturera först nästa månad'
],
entries = range(0, batchSize).map(function() {
return {
type: 'entry',
activity: activities[i % activities.length],
referencenumber: i % projects.length,
project: projects[i % projects.length],
customer: customers[i % customers.length],
time: (((i % 9) + '').replace(/,/g, '.') * 1),
description: descriptions[i % descriptions.length],
date: new Date(i * 86400)
};
});
return db.bulkDocs({docs: entries}, function(err, response) {
var i;
if (response) {
for (i = response.length - 1; i >= 0; i--) {
docs.push({id: response[i].id, rev: response[i].rev});
}
}
});
}
function getDocuments() {
var id = docs[Math.floor(Math.random() * docs.length)].id;
return db.get(id, function(err, response) {
if (err) {
console.log(err);
}
});
}
function query(i) {
return db.query(testQuery,
function(err, response) {
if (err) {
console.log(err);
}
});
}
console.log('Pouch-Couch Benchmark');
console.log('=====================');
console.log(dbName);
console.log('nDocs: ' + nDocs + ', scrap: ' + nDocs * scrapFactor);
setUp();
createScrap(nDocs * scrapFactor).
then(function() { return time(createDocuments, nDocs / batchSize); }).
then(function() { return time(getDocuments, 1000); }).
then(function() { return time(query, 1000, true); }, function(err) {
console.log(err);
}).
then(tearDown).
catch(function(e) { console.log(e); tearDown(); });

PouchDB Benchmarks

IndexedDB

Operations over all documents

# docs Create Get Sum
1 649 0.65 1.35
10 51 0.4 3
100 8.02 0.4 20.85
1000 2.32 0.5 172.5
10000 4.31 0.5 3198

Operations over a subset of all documents

Using 10% of all docs

# docs Create Get Sum Total # docs
1 2 0.45 2.8 11
10 2.1 0.4 21.8 110
100 1.73 0.5 182.2 1100
1000 2.32 0.45 3163 11000

Tests for 10000 docs omitted, since it takes unreasonable amounts of time to complete.

CouchDB

Operations over all documents

# docs Create Get Sum (temp) Sum (view)
1 29 3 1.9 3.1
10 8.2 3.4 2.3 2.6
100 6.0 3.5 3.7 3.1
1000 5.8 3.5 8.5 3.2

Test for 10000 docs omitted, since inserting docs one by one stops working here (my guess: too many concurrent requests for Couch to handle). Switching to bulk insert, which changes performance profile for the create operation.

# docs Create Get Sum (temp) Sum (view)
10000 9.7 3.5 60 3.7

Operations over a subset of all documents

Again, logic must be changed to avoid absurd concurrency - query is now run sequentially instead of in paralell, possibly reducing performance somewhat (all cores not necessarily used efficiently).

# docs Create Get Sum (view) Total # docs
1 13.4 2.7 6.9 ~100,000
10 11.0 2.7 7.2 ~100,000
100 13.8 2.7 7.0 ~100,000
1000 13.6 2.7 7.2 ~101,000
10000 8.5 2.6 8.4 ~110,000
10000 7.0 2.8 8.4 ~1,000,000
@mohataher
Copy link

mohataher commented Aug 30, 2020

What do these numbers represent? Is it milliseconds, seconds, minutes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment