Skip to content

Instantly share code, notes, and snippets.

@webstrand
Last active March 12, 2020 20:22
Show Gist options
  • Select an option

  • Save webstrand/e81a760ab3026cc2b9c2d2e34a92dee0 to your computer and use it in GitHub Desktop.

Select an option

Save webstrand/e81a760ab3026cc2b9c2d2e34a92dee0 to your computer and use it in GitHub Desktop.
benchmarking inheritance vs composition
const Benchmark = require("benchmark");
console.log("setup");
var suite = new Benchmark.Suite();
class TestInheritance extends Set {
constructor() { super() }
op(q) { this.add(q) }
}
const obj = [[1],[2],[3],[4],[5],[6],[7],[8],[9]];
class TestComposition {
constructor() { this.set = new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]) }
op(q) { this.set.add(q) }
clear() { this.set.clear() }
}
class TestCompositionFrozen {
constructor() { this.set = new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]); Object.freeze(this) }
op(q) { this.set.add(q) }
clear() { this.set.clear() }
}
class TestCompositionDeclared {
constructor() { Object.defineProperty(this, "set", { value: new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]) }) }
op(q) { this.set.add(q) }
clear() { this.set.clear() }
}
class TestCompositionDeclaredManual {
constructor() { Object.defineProperty(this, "set", { value: new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]), writable: false, configurable: false, enumerable: false }) }
op(q) { this.set.has(q); }
clear() { this.set.clear() }
}
class TestCompositionDeclaredWritable {
constructor() { Object.defineProperty(this, "set", { value: new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]), writable: true, configurable: false, enumerable: false }) }
op(q) { this.set.add(q) }
clear() { this.set.clear() }
}
function TestClosure() {
const set = new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]);
return {
op(q) { set.add(q) },
clear() { set.clear() }
}
}
function TestSimpleComposition() {
return {
set: new Set([obj[1],obj[3],obj[5],obj[7],obj[9]]),
op(q) { this.set.add(q) },
clear() { this.set.clear() }
}
}
let inheritance = new TestInheritance();
let composition = new TestComposition();
let compositionFrozen = new TestCompositionFrozen();
let compositionDeclared = new TestCompositionDeclared();
let compositionDeclaredManual = new TestCompositionDeclaredManual();
let compositionDeclaredWritable = new TestCompositionDeclaredWritable();
let closure = TestClosure();
let simpleComposition = TestSimpleComposition();
suite
.add("Composition Declared", function () {
let q = 0;
compositionDeclared.op(obj[q++]);
compositionDeclared.op(obj[q++]);
compositionDeclared.op(obj[q++]);
compositionDeclared.op(obj[q++]);
compositionDeclared.clear();
})
.add("Composition Declared Manual", function () {
let q = 0;
compositionDeclaredManual.op(obj[q++]);
compositionDeclaredManual.op(obj[q++]);
compositionDeclaredManual.op(obj[q++]);
compositionDeclaredManual.op(obj[q++]);
compositionDeclaredManual.clear();
})
.add("Closure", function () {
let q = 0;
closure.op(obj[q++]);
closure.op(obj[q++]);
closure.op(obj[q++]);
closure.op(obj[q++]);
closure.clear();
})
.add("Simple Composition", function () {
let q = 0;
simpleComposition.op(obj[q++]);
simpleComposition.op(obj[q++]);
simpleComposition.op(obj[q++]);
simpleComposition.op(obj[q++]);
simpleComposition.clear();
})
.add("Inheritance", function () {
let q = 0;
inheritance.op(obj[q++]);
inheritance.op(obj[q++]);
inheritance.op(obj[q++]);
inheritance.op(obj[q++]);
inheritance.clear();
})
.add("Composition", function () {
let q = 0;
composition.op(obj[q++]);
composition.op(obj[q++]);
composition.op(obj[q++]);
composition.op(obj[q++]);
composition.clear();
})
.add("Composition Frozen", function () {
let q = 0;
compositionFrozen.op(obj[q++]);
compositionFrozen.op(obj[q++]);
compositionFrozen.op(obj[q++]);
compositionFrozen.op(obj[q++]);
compositionFrozen.clear();
})
.add("Composition Declared Writable", function () {
let q = 0;
compositionDeclaredWritable.op(obj[q++]);
compositionDeclaredWritable.op(obj[q++]);
compositionDeclaredWritable.op(obj[q++]);
compositionDeclaredWritable.op(obj[q++]);
compositionDeclaredWritable.clear();
})
.run({ 'async': false });
suite.on('cycle', function(event) {
console.log(String(event.target));
console.log(event.target.name);
console.log(event.target.stats.rme);
console.log(event.target.stats.sample.length);
console.log(event.target.count); // The number of times a test was executed.
console.log(event.target.cycles); // The number of cycles performed while benchmarking.
console.log(event.target.hz); //The number of executions per second.
})
.on('complete', function() {
for (var i = 0; i < this.length; i++) {
console.log(this[i].name, this[i].hz + " ops/sec");
console.log(this[i].stats.sample.length);
//console.log(this[i].stats);
}
console.log('Fastest is ' + this.filter('fastest').map('name'));
console.log('Slowest is ' + this.filter('slowest').map('name'));
})
.run({ 'async': false });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment