Socket
Socket
Sign inDemoInstall

better-sqlite3

Package Overview
Dependencies
Maintainers
1
Versions
129
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

better-sqlite3 - npm Package Compare versions

Comparing version 2.1.0 to 2.2.0

benchmark/factory.js

112

benchmark/index.js

@@ -6,75 +6,67 @@ 'use strict';

var spawn = require('child_process').spawn;
var factory = require('./factory');
process.chdir(path.dirname(__dirname));
process.on('SIGINT', exit);
process.on('SIGHUP', exit);
process.on('SIGTERM', exit);
var trials;
fs.removeSync('temp/');
fs.ensureDirSync('temp/');
process.on('SIGINT', function () {fs.removeSync('temp/'); process.exit();});
process.on('SIGHUP', function () {fs.removeSync('temp/'); process.exit();});
process.on('SIGTERM', function () {fs.removeSync('temp/'); process.exit();});
var trials = fs.readdirSync(path.join(__dirname, 'trials')).filter(function (name) {return name[0] !== '.';});
if (!trials.length) {
console.log(clc.yellow('No benchmarks exist!'));
(function init() {
fs.removeSync('temp/');
process.exit();
}
fs.ensureDirSync('temp/');
trials = getTrials();
if (!trials.length) {
console.log(clc.yellow('No matching benchmarks found!'));
return exit();
}
console.log('Generating tables...');
factory.buildTables().then(function () {
console.log(clc.magenta('--- Benchmarks ---'));
nextTrial();
}, function (err) {
console.log(clc.red(err && err.stack || err));
exit(1);
});
}());
console.log('Generating tables...');
var createdCount = 0;
function created() {
if (++createdCount === 8) {
console.log(clc.magenta('--- Benchmarks ---'));
next();
function getTrials() {
return process.argv.slice(2).reduce(filterByArgs, require('./trials').map(addSearchTerms));
function addSearchTerms(trial) {
var size = trial.table.toLowerCase().indexOf('large') === -1 ? 'small' : 'large';
var columns = trial.columns.join(',').toLowerCase();
if (trial.columns.length > 1) {columns = '(' + columns + ')';}
trial.terms = [trial.type.toLowerCase(), size, columns];
trial.looseTerms = (trial.pragma || []).filter(customPragma).join('; ').toLowerCase();
return trial;
}
function filterByArgs(trials, arg) {
arg = arg.toLowerCase();
return trials.filter(function (obj) {
return obj.terms.indexOf(arg) !== -1 || obj.looseTerms.indexOf(arg) !== -1;
});
}
function customPragma(str) {
return str.indexOf('cache_size') === -1;
}
}
require('./create-table')('CREATE TABLE entries (text TEXT, integer INTEGER, real REAL, blob BLOB, nul)', 'select-small', fillSmallDataTable);
require('./create-table')('CREATE TABLE entries (text TEXT, blob BLOB)', 'select-large', function (ourDb, theirDb) {
var bigString = '';
while (bigString.length < 1024 * 1024) {
bigString += 'John Peter Smith';
}
var values = {
a: bigString,
b: Buffer.alloc(1024 * 1024).fill(0xdd)
};
var filledCount = 0;
function filled() {++filledCount === 2 && created();}
require('./fill-table')(ourDb, 1000, 'INSERT INTO entries VALUES (@a, @b)', values, filled);
require('./fill-table')(theirDb, 1000, 'INSERT INTO entries VALUES (@a, @b)', values, filled);
});
require('./create-table')('CREATE TABLE entries (data TEXT)', 'insert-text', created);
require('./create-table')('CREATE TABLE entries (data INTEGER)', 'insert-integer', created);
require('./create-table')('CREATE TABLE entries (data REAL)', 'insert-real', created);
require('./create-table')('CREATE TABLE entries (data BLOB)', 'insert-blob', created);
require('./create-table')('CREATE TABLE entries (data)', 'insert-null', created);
require('./create-table')('CREATE TABLE entries (text TEXT, integer INTEGER, real REAL, blob BLOB, nul)', 'real-world', fillSmallDataTable);
function fillSmallDataTable(ourDb, theirDb) {
var values = {
a: 'John Peter Smith',
b: 12345,
c: 0.12345,
d: Buffer.alloc(16).fill(0xdd),
e: null
};
var filledCount = 0;
function filled() {++filledCount === 2 && created();}
require('./fill-table')(ourDb, 1000, 'INSERT INTO entries VALUES (@a, @b, @c, @d, @e)', values, filled);
require('./fill-table')(theirDb, 1000, 'INSERT INTO entries VALUES (@a, @b, @c, @d, @e)', values, filled);
function exit(code) {
fs.removeSync('temp/');
process.exit(typeof code === 'number' ? code : 0);
}
function next() {
function nextTrial() {
if (!trials.length) {
console.log(clc.green('All benchmarks complete!'));
fs.removeSync('temp/');
process.exit();
return exit();
}
var trialName = trials.shift();
var trial = trials.shift();
var extraName = trial.looseTerms ? clc.yellow(' | ' + trial.looseTerms) : '';
console.log(clc.cyan(trial.terms.join(' ')) + extraName);
console.log(clc.cyan(trialName));
var child = spawn('node', ['--expose-gc', path.join(__dirname, 'trials', trialName)], {stdio: 'inherit'});
var child = spawn('node', [path.join(__dirname, 'types', trial.type), JSON.stringify(trial)], {stdio: 'inherit'});
child.on('exit', function (code) {

@@ -84,4 +76,4 @@ if (code !== 0) {

}
setTimeout(next, 100);
setTimeout(nextTrial, 0);
});
}
'use strict';
exports = module.exports = function (ourDb, theirDb, count, data) {
function callback0() {
global.gc();
ourTest(ourDb, count, data, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, data, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, data, done) {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
exports.data = db.prepare('INSERT INTO entries VALUES (?)').run(data);
}
var td = process.hrtime(t0);
report('better-sqlite3', count, td);
done();
}
function theirTest(db, count, data, done) {
var completed = 0;
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.run('INSERT INTO entries VALUES (?)', data, callback);
}
function callback(err) {
exports.data = this;
if (err) {throw err;}
if (++completed === count) {
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' INSERTs in ' + ms + 'ms');
}
// Inserts 1 row
require('../runner')(function (benchmark, dbs, ctx) {
var factory = require('../factory');
var SQL = 'INSERT INTO ' + ctx.table + ' (' + ctx.columns.join(', ') + ') VALUES ' + factory.params(ctx.columns.length);
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var data = factory(ctx.table, ctx.columns);
var stmt = betterSqlite3.prepare(SQL);
benchmark.add('better-sqlite3', function () {
betterSqlite3.prepare(SQL).run(data);
});
benchmark.add(' + optimized', function () {
stmt.run(data);
});
benchmark.add('node-sqlite3', function (deferred) {
nodeSqlite3.run(SQL, data).then(function () {deferred.resolve();});
});
});
'use strict';
exports = module.exports = function (ourDb, theirDb, count, countPerCycle) {
if (countPerCycle > 1000) {
throw new Error('countPerCycle must be <= 1000');
}
if (count % countPerCycle !== 0) {
count = count + countPerCycle - count % countPerCycle;
}
// Concurrently reads and writes single rows
require('../runner')(function (benchmark, dbs, ctx) {
var factory = require('../factory');
var SELECT = 'SELECT ' + ctx.columns.join(', ') + ' FROM ' + ctx.table + ' WHERE rowid=?';
var INSERT = 'INSERT INTO ' + ctx.table + ' (' + ctx.columns.join(', ') + ') VALUES ' + factory.params(ctx.columns.length);
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var data = factory(ctx.table, ctx.columns);
var rowid = 0;
benchmark.on('cycle', function () {rowid = 0;});
var params = [
'John Peter Smith',
12345,
0.12345,
Buffer.alloc(16).fill(0xdd),
null
];
var betterSqlite3Select = betterSqlite3.prepare(SELECT);
var betterSqlite3Insert = betterSqlite3.prepare(INSERT);
function callback0() {
global.gc();
ourTest(ourDb, count, countPerCycle, params, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, countPerCycle, params, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, countPerCycle, params, done) {
var requested = 0;
var t0 = process.hrtime();
(function request() {
for (var i=0; i<countPerCycle; ++i) {
if (i % 2) {
exports.data = db.prepare('INSERT INTO entries VALUES (?, ?, ?, ?, ?)').run(params);
} else {
exports.data = db.prepare('SELECT * FROM entries WHERE rowid=?').get(i % 1000 + 1);
}
}
if ((requested += countPerCycle) < count) {
setImmediate(request);
benchmark.add('better-sqlite3', function () {
if (rowid % 2) {betterSqlite3Select.get(rowid % 1000 + 1);}
else {betterSqlite3Insert.run(data);}
rowid += 1;
});
benchmark.add('node-sqlite3', function (deferred) {
if (rowid % 2) {
nodeSqlite3.get(SELECT, rowid % 1000 + 1).then(function () {deferred.resolve();});
} else {
var td = process.hrtime(t0);
report('better-sqlite3', count, td);
done();
nodeSqlite3.run(INSERT, data).then(function () {deferred.resolve();});
}
}());
}
function theirTest(db, count, countPerCycle, params, done) {
var requested = 0;
var completed = 0;
var t0 = process.hrtime();
(function request() {
for (var i=0; i<countPerCycle; ++i) {
if (i % 2) {
db.run('INSERT INTO entries VALUES (?, ?, ?, ?, ?)', params, callback);
} else {
db.get('SELECT * FROM entries WHERE rowid=?', i % 1000 + 1, callback);
}
}
if ((requested += countPerCycle) < count) {
setImmediate(request);
}
}());
function callback(err, data) {
exports.data = data || this;
if (err) {throw err;}
if (++completed === count) {
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' INSERT or SELECTs in ' + ms + 'ms');
}
rowid += 1;
});
});
'use strict';
var RPS;
exports = module.exports = function (ourDb, theirDb, count, rowsPerSelect, columnName) {
if (rowsPerSelect > 1000) {
throw new Error('rowsPerSelect cannot be greater than 1000');
}
if (rowsPerSelect === 1000) {
var SQL = 'SELECT ' + columnName + ' FROM entries';
} else {
var SQL = 'SELECT ' + columnName + ' FROM entries WHERE rowid <= ' + rowsPerSelect;
}
RPS = rowsPerSelect;
// Selects 100 rows
require('../runner')(function (benchmark, dbs, ctx) {
var SQL = 'SELECT ' + ctx.columns.join(', ') + ' FROM ' + ctx.table + ' WHERE rowid>=? LIMIT 100';
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var rowid = 99;
benchmark.on('cycle', function () {rowid = 0;});
function callback0() {
global.gc();
ourTest(ourDb, count, SQL, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, SQL, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, SQL, done) {
if (!/^\s*(no|off|0|false)\s*$/i.test(process.env.USE_PLUCK)) {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
exports.data = db.prepare(SQL).pluck().all();
}
} else {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
exports.data = db.prepare(SQL).all();
}
}
var td = process.hrtime(t0);
report('better-sqlite3', count, td);
done();
}
function theirTest(db, count, SQL, done) {
var completed = 0;
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.all(SQL, callback);
}
function callback(err, data) {
exports.data = data;
if (err) {throw err;}
if (++completed === count) {
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' SELECTs (' + RPS + ' rows each) in ' + ms + 'ms');
}
var stmt = betterSqlite3.prepare(SQL).pluck();
benchmark.add('better-sqlite3', function () {
betterSqlite3.prepare(SQL).all(rowid % 1000 - 98);
rowid += 100;
});
benchmark.add(' + optimized', function () {
stmt.all(rowid % 1000 - 98);
rowid += 100;
});
benchmark.add('node-sqlite3', function (deferred) {
nodeSqlite3.all(SQL, rowid % 1000 - 98).then(function () {deferred.resolve();});
rowid += 100;
});
});
'use strict';
var RPS;
exports = module.exports = function (ourDb, theirDb, count, rowsPerSelect, columnName) {
if (rowsPerSelect > 1000) {
throw new Error('rowsPerSelect cannot be greater than 1000');
}
if (rowsPerSelect === 1000) {
var SQL = 'SELECT ' + columnName + ' FROM entries';
} else {
var SQL = 'SELECT ' + columnName + ' FROM entries WHERE rowid <= ' + rowsPerSelect;
}
RPS = rowsPerSelect;
// Selects 100 rows
require('../runner')(function (benchmark, dbs, ctx) {
var SQL = 'SELECT ' + ctx.columns.join(', ') + ' FROM ' + ctx.table + ' WHERE rowid>=? LIMIT 100';
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var rowid = 99;
benchmark.on('cycle', function () {rowid = 0;});
function callback0() {
global.gc();
ourTest(ourDb, count, SQL, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, SQL, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, SQL, done) {
if (!/^\s*(no|off|0|false)\s*$/i.test(process.env.USE_PLUCK)) {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.prepare(SQL).pluck().each(dataCallback);
}
} else {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.prepare(SQL).each(dataCallback);
}
}
function dataCallback(data) {
exports.data = data;
}
var td = process.hrtime(t0);
report('better-sqlite3', count, td);
done();
}
function theirTest(db, count, SQL, done) {
var completed = 0;
var partialCompleted = 0;
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.each(SQL, dataCallback);
}
function dataCallback(err, data) {
exports.data = data;
if (err) {throw err;}
if (++partialCompleted === 1000) {
partialCompleted = 0;
callback();
}
}
function callback() {
if (++completed === count) {
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' SELECTs (' + RPS + ' rows each) in ' + ms + 'ms');
}
var stmt = betterSqlite3.prepare(SQL).pluck();
benchmark.add('better-sqlite3', function () {
betterSqlite3.prepare(SQL).each(rowid % 1000 - 98, function () {});
rowid += 100;
});
benchmark.add(' + optimized', function () {
stmt.each(rowid % 1000 - 98, function () {});
rowid += 100;
});
benchmark.add('node-sqlite3', function (deferred) {
nodeSqlite3.each(SQL, rowid % 1000 - 98, function () {}).then(function () {deferred.resolve();});
rowid += 100;
});
});
'use strict';
exports = module.exports = function (ourDb, theirDb, count, columnName) {
var SQL = 'SELECT ' + columnName + ' FROM entries WHERE rowid=?';
// Selects 1 row
require('../runner')(function (benchmark, dbs, ctx) {
var SQL = 'SELECT ' + ctx.columns.join(', ') + ' FROM ' + ctx.table + ' WHERE rowid=?';
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var rowid = 0;
benchmark.on('cycle', function () {rowid = 0;});
function callback0() {
global.gc();
ourTest(ourDb, count, SQL, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, SQL, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, SQL, done) {
if (!/^\s*(no|off|0|false)\s*$/i.test(process.env.USE_PLUCK)) {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
exports.data = db.prepare(SQL).pluck().get(i % 1000 + 1);
}
} else {
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
exports.data = db.prepare(SQL).get(i % 1000 + 1);
}
}
var td = process.hrtime(t0);
report('better-sqlite3', count, td);
done();
}
function theirTest(db, count, SQL, done) {
var completed = 0;
var t0 = process.hrtime();
for (var i=0; i<count; ++i) {
db.get(SQL, i % 1000 + 1, callback);
}
function callback(err, data) {
exports.data = data;
if (err) {throw err;}
if (++completed === count) {
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' SELECTs in ' + ms + 'ms');
}
var stmt = betterSqlite3.prepare(SQL).pluck();
benchmark.add('better-sqlite3', function () {
betterSqlite3.prepare(SQL).get(rowid++ % 1000 + 1);
});
benchmark.add(' + optimized', function () {
stmt.get(rowid++ % 1000 + 1);
});
benchmark.add('node-sqlite3', function (deferred) {
nodeSqlite3.get(SQL, rowid++ % 1000 + 1).then(function () {deferred.resolve();});
});
});
'use strict';
exports = module.exports = function (ourDb, theirDb, count, data) {
function callback0() {
global.gc();
ourTest(ourDb, count, data, callback1);
}
function callback1() {
global.gc();
theirTest(theirDb, count, data, callback2);
}
function callback2() {
ourDb.close();
theirDb.close(process.exit);
}
setTimeout(callback0, 100);
};
exports.data = undefined;
function ourTest(db, count, data, done) {
data = {data: data};
var statements = new Array(count).fill('INSERT INTO entries VALUES (@data);');
// Inserts 100 rows
require('../runner')(function (benchmark, dbs, ctx) {
var SQL = 'INSERT INTO ' + ctx.table + ' (' + ctx.columns.join(', ') + ') VALUES (' + namedParams(ctx.columns).join(', ') + ')';
var betterSqlite3 = dbs['better-sqlite3'];
var nodeSqlite3 = dbs['node-sqlite3'];
var data = namedData(ctx.table, ctx.columns);
var dataWithPrefix = namedData(ctx.table, ctx.columns, true);
var t0 = process.hrtime();
exports.data = db.transaction(statements).run(data);
var td = process.hrtime(t0);
var transaction = betterSqlite3.transaction(new Array(100).fill(SQL));
report('better-sqlite3', count, td);
done();
benchmark.add('better-sqlite3', function () {
betterSqlite3.transaction(new Array(100).fill(SQL)).run(data);
});
benchmark.add(' + optimized', function () {
transaction.run(data);
});
benchmark.add('node-sqlite3', function (deferred) {
var count = 0;
nodeSqlite3.run('BEGIN').then(function insert() {
if (++count < 100) {
return nodeSqlite3.run(SQL, dataWithPrefix).then(insert);
}
return nodeSqlite3.run(SQL, dataWithPrefix).then(function () {
return nodeSqlite3.run('COMMIT').then(function () {deferred.resolve();});
});
});
});
});
function namedParams(columns) {
return columns.map(function (_, i) {return '@x' + i;});
}
function theirTest(db, count, data, done) {
data = {'@data': data};
function run() {
db.run('BEGIN TRANSACTION;', checkForError);
for (var i=0; i<count; ++i) {
db.run('INSERT INTO entries VALUES (@data);', data, checkForError);
}
db.run('COMMIT TRANSACTION;', callback);
}
function checkForError(err) {
if (err) {throw err;}
}
var t0 = process.hrtime();
db.serialize(run);
function callback(err) {
exports.data = this;
checkForError(err);
var td = process.hrtime(t0);
report('node-sqlite3', count, td);
done();
}
}
function report(name, count, time) {
var ms = time[0] * 1000 + Math.round(time[1] / 1000000);
console.log(name + '\t' + count + ' INSERTs (single TRANSACTION) in ' + ms + 'ms');
function namedData(table, columns, withPrefix) {
var data = require('../factory')(table, columns);
var bindNames = namedParams(columns);
var wrappedData = data.map(function (item, i) {
var wrappedItem = {};
wrappedItem[withPrefix ? bindNames[i] : bindNames[i].slice(1)] = item;
return wrappedItem;
});
return Object.assign.apply(Object, [{}].concat(wrappedData));
}
{
"name": "better-sqlite3",
"version": "2.1.0",
"version": "2.2.0",
"description": "The fastest and simplest library for SQLite3 in Node.js.",

@@ -18,2 +18,3 @@ "homepage": "http://github.com/JoshuaWise/better-sqlite3",

"devDependencies": {
"benchmark": "^2.1.4",
"chai": "^3.5.0",

@@ -23,3 +24,3 @@ "cli-color": "^1.1.0",

"mocha": "^3.0.2",
"sqlite3": "^3.1.4"
"sqlite": "^2.5.0"
},

@@ -26,0 +27,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc