Created
November 20, 2012 23:07
-
-
Save caridy/4121888 to your computer and use it in GitHub Desktop.
Perf optimization for function hooks in Node.JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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