diff --git a/package.json b/package.json index edf9083..1fb81ec 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "request-promise": "4.0.2" }, "devDependencies": { + "benchmark": "2.1.1", "coveralls": "2.11.11", "eslint": "3.0.1", "ghooks": "1.2.4", diff --git a/proxy-benchmark.js b/proxy-benchmark.js new file mode 100644 index 0000000..ec8708d --- /dev/null +++ b/proxy-benchmark.js @@ -0,0 +1,50 @@ +'use strict' + +const benchmark = require('benchmark') +const list = [1, 2, 3, 4, 5] + +const sum = () => { + let total = 0 + for (let i = 0; i < list.length; i++) { + total += list[i] + } + return total +} + +// simple object +const obj = {sum} + +// proxy that wraps an empty object +const emptyProxy = new Proxy({}, { + get(target, key) { + if (key === 'sum') { + return obj.sum + } + return undefined // eslint-disable-line no-undefined + } +}) + +// no-op proxy around +const noopProxy = new Proxy(obj, {}) + +// one-time proxy +const handler = { + get(target, key) { + target.sum = sum + delete handler.get + return target[key] + } +} +const oneTimeProxy = new Proxy({}, handler) + +new benchmark.Suite().add('normal method', () => + obj.sum() +).add('proxy', () => + emptyProxy.sum() +).add('no-op proxy', () => + noopProxy.sum() +).add('one time proxy', () => + oneTimeProxy.sum() +).on('cycle', ({target}) => + console.log(target.toString()) // eslint-disable-line no-console +).run() diff --git a/test/client.js b/test/client.js index ca09e2d..a2013d3 100644 --- a/test/client.js +++ b/test/client.js @@ -2,9 +2,10 @@ const Lab = require('lab') const assert = require('power-assert') const moment = require('moment') const bunyan = require('bunyan') +const request = require('request-promise') const {getClient, startServer} = require('../') const {version} = require('../package.json') -const utils = require('./utils') +const utils = require('./test-utils') const lab = exports.lab = Lab.script() const {describe, it, before, beforeEach, after} = lab @@ -125,6 +126,62 @@ describe('service\'s client', () => { after(() => server.stop()) declareTests(context) + + it('should not add too much overhead', {timeout: 15e3}, () => { + + const benchmark = { + client: () => context.client.greeting('Jane'), + direct: () => request({ + method: 'POST', + uri: `${server.info.uri}/api/sample/greeting`, + body: {name: 'Jane'}, + json: true + }) + } + const run = (name, results, start, duration) => { + const end = () => { + if (Date.now() - start >= duration) { + return Promise.resolve() + } + return run(name, results, start, duration) + } + + return benchmark[name]() + .then(() => { + results.count++ + return end() + }) + .catch(err => { + results.errored++ + results.errors.push(err) + return end() + }) + } + + const runBench = (names, results = {}) => { + if (names.length === 0) { + return Promise.resolve(results) + } + const name = names.shift() + results[name] = {count: 0, errored: 0, errors: []} + // heating run + return run(name, {count: 0, errored: 0, errors: []}, Date.now(), 1e3) + // test run + .then(() => run(name, results[name], Date.now(), 5e3)) + // next bench + .then(() => runBench(names, results)) + } + + return runBench(Object.keys(benchmark)) + .then(results => { + const percentage = results.client.count * 100 / results.direct.count + assert(results.direct.count > 1000) + assert(results.client.count > 1000) + assert.equal(results.direct.errored, 0) + assert.equal(results.client.errored, 0) + assert(percentage >= 80) + }) + }) }) describe('a remote client without server', () => { diff --git a/test/server.js b/test/server.js index 437e22a..7cd04da 100644 --- a/test/server.js +++ b/test/server.js @@ -3,7 +3,7 @@ const bunyan = require('bunyan') const assert = require('power-assert') const request = require('request-promise') const {startServer} = require('../') -const utils = require('./utils') +const utils = require('./test-utils') const lab = exports.lab = Lab.script() const {describe, it, before, beforeEach, after, afterEach} = lab diff --git a/test/utils.js b/test/test-utils.js similarity index 100% rename from test/utils.js rename to test/test-utils.js