Skip to content

Instantly share code, notes, and snippets.

@perliedman
Last active March 31, 2024 18:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save perliedman/9388569 to your computer and use it in GitHub Desktop.
Save perliedman/9388569 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 |
@rluvaton
Copy link

rluvaton commented Feb 7, 2019

Fix the result file name forked gist

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