From 331f0a6a0cc755823ee5437386a25c690fe1c1a9 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Mon, 31 Oct 2022 00:18:06 +0100 Subject: [PATCH] Support measuring the cost of hooks and events Ref https://github.com/Level/abstract-level/pull/45 --- benchmarks/batch-put.js | 2 +- lib/meta.js | 2 ++ lib/run.js | 50 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/benchmarks/batch-put.js b/benchmarks/batch-put.js index 6306e97..658468f 100644 --- a/benchmarks/batch-put.js +++ b/benchmarks/batch-put.js @@ -48,7 +48,7 @@ exports.run = function (factory, stream, options) { function report () { console.log( 'Wrote', options.n, 'entries in', - Math.floor((Date.now() - startTime) / 1e3) + 's,', + ((Date.now() - startTime) / 1e3).toFixed(2) + 's,', (Math.floor((totalBytes / 1048576) * 100) / 100) + 'MB' ) diff --git a/lib/meta.js b/lib/meta.js index a84390c..f66ec67 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -103,6 +103,8 @@ function id (meta, peers, invert, opts) { } } else if (path.length > 2) { parts.push(`${path.slice(2).join('.')}.${k}=${v}`) + } else if (path.length === 2 && path[0] === 'options' && (path[1] === 'events' || path[1] === 'hooks')) { + parts.push(`${path[1]}.${k}=${v}`) } else if (typeof v === 'boolean') { parts.push(v ? k : `!${k}`) } else if (typeof v === 'number') { diff --git a/lib/run.js b/lib/run.js index 204ca62..ae5633d 100644 --- a/lib/run.js +++ b/lib/run.js @@ -87,6 +87,50 @@ module.exports = function (benchmark, targetId, options) { mkdirp.sync(path.dirname(csvFile)) + const addHooksAndEvents = (db) => { + // Test the cost of adding X amount of hook functions + // E.g. level-bench run batch-put ../memory-level --hooks [ --prewrite=1 ] + // TODO: docs + if (options.hooks) { + for (const name of ['prewrite']) { + const count = parseInt(options.hooks[name] || 0, 10) + + if (!Number.isInteger(count) || count < 0) { + throw new RangeError(`The "hooks.${name}" option must be >= 0`) + } + + if (count > 0 && (!db.hooks || !db.hooks[name])) { + throw new Error(`Database does not support ${name} hook`) + } + + for (let i = 0; i < count; i++) { + db.hooks[name].add(function () {}) + } + } + } + + // Test the cost of adding X amount of event listeners + // E.g. level-bench run batch-put ../memory-level --events [ --write=1 ] + // TODO: docs + if (options.events) { + for (const name of ['write', 'batch', 'put', 'del']) { + const count = parseInt(options.events[name] || 0, 10) + + if (!Number.isInteger(count) || count < 0) { + throw new RangeError(`The "events.${name}" option must be >= 0`) + } + + if (count > 0 && (!db.supports.events || !db.supports.events[name])) { + throw new Error(`Database does not support ${name} event`) + } + + for (let i = 0; i < count; i++) { + db.on(name, function () {}) + } + } + } + } + let factory if (name === 'rave-level') { @@ -103,6 +147,7 @@ module.exports = function (benchmark, targetId, options) { leader.getMany(['x'], function (err) { if (err) throw err const follower = target(loc) + addHooksAndEvents(follower) follower.open((err) => cb(err, follower)) }) }) @@ -113,6 +158,7 @@ module.exports = function (benchmark, targetId, options) { factory = (cb) => { const db = dbFactory(options.location) + addHooksAndEvents(db) db.open((err) => cb(err, db)) } } @@ -131,7 +177,9 @@ module.exports = function (benchmark, targetId, options) { class: undefined, db: options.db, - benchmark: options.benchmark + benchmark: options.benchmark, + hooks: options.hooks || undefined, + events: options.events || undefined } })