Skip to content

Instantly share code, notes, and snippets.

@caridy
Created November 20, 2012 23:07
Show Gist options
  • Save caridy/4121888 to your computer and use it in GitHub Desktop.
Save caridy/4121888 to your computer and use it in GitHub Desktop.
Perf optimization for function hooks in Node.JS
var microtime = require('microtime'),
i,
t,
obj,
max = 10000000;
function run1(obj) {
t = microtime.now();
for (i = 0; i < max; i += 1) {
if (obj.foo) obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'conditional to true');
}
function run2(obj) {
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.foo && obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'true && function()');
}
function run3(obj) {
obj.foo = null; // seeting value to falsy
t = microtime.now();
for (i = 0; i < max; i += 1) {
if (obj.foo) obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'conditional to false setting value to null');
}
function run4(obj) {
obj.foo = null; // seeting value to falsy
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.foo && obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'false && function()');
}
function run5(obj) {
delete obj.foo; // deleting member
t = microtime.now();
for (i = 0; i < max; i += 1) {
if (obj.foo) obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'conditional to false by deleting member');
}
function run6(obj) {
delete obj.foo; // deleting member
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.foo && obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'undefined && function() by deleting member');
}
function run7(obj) {
t = microtime.now();
for (i = 0; i < max; i += 1) {
if (obj.foo) obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'conditional to undefined');
}
function run8(obj) {
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.foo && obj.foo();
obj.run();
}
console.log(microtime.now() - t, 'undefined && function()');
}
function run9(obj) {
// conditional to true
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.run();
}
console.log(microtime.now() - t, 'function without replace');
}
function run10(obj) {
// wrapping original function
obj._run = obj.run;
obj.run = function () {
this.foo();
this._run();
};
t = microtime.now();
for (i = 0; i < max; i += 1) {
obj.run();
}
console.log(microtime.now() - t, 'function with replace');
}
run9({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run10({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run2({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run4({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
console.log('--------------');
run1({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run3({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run5({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run6({
foo: function () {
var f = 1;
},
run: function () {
var f = 1;
}
});
run7({
// foo is undefined here
run: function () {
var f = 1;
}
});
run8({
// foo is undefined here
run: function () {
var f = 1;
}
});
On 10 millions iteration
With the hook disabled we can compare:
--------------------------------------
109133 'function without replace'
143334 'false && function()'
result: ~23% slower by having a hook in the runtime when it is not in use.
With the hook enabled we can compare:
-------------------------------------
242666 'function with replace (with 3 func calls, original, wrapper and foo)'
219787 'true && function() (with 2 func calls, original and foo)'
result: ~10% faster by having a hook in the runtime when it is in use.
Other results:
148395 'conditional to false setting value to null'
146548 'false && function()'
2155216 'conditional to false by deleting member'
2170832 'undefined && function() by deleting member'
146075 'conditional to undefined'
146458 'undefined && function()'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment