props or proto on fns
JavaScript performance comparison
Info
In some random google talk I watch on youtube, it was described that it's fastest to prefer using as many literals as possible, instead of adding things as properties. For example, this is bad: var a = new Array() a[1] = 'a' a[3] = 2 ... vs the one line literal var a = [undefined, 'a', undefined, 2];
So how does this apply to functions that are modules, like jQuery for example?
Preparation code
//some real code! function historicalConsole(fn, optionalName) { if (optionalName
&& historicalConsole[optionalName]) { //names not supported quite yet //return historicalConsole[optionalName];
} //validate callback: if (Object.prototype.toString.call(fn) != '[object Function]'
|| arguments.length !== 1 || fn.length !== 1) { var message = 'historicalConsole
expects one function argument like this: ' + 'historicalConsole(function(console){/*your
whole program*/});'; alert(message); console.error(message + ' You passed in these
arguments: ', arguments); return; } //returning a function allows for more flexible
use of `historicalConsole` return function historicalConsoleClosure() { if (arguments.length
> 0) { console.warn( 'The function returned from historicalConsole does not take
arguments. ' + 'These arguments will be ignored. You\'re probably doing something
wrong' ); } //override global console temporarily so that console.* calls from externals
//are logged too. This could be developer feedback from external libraries //regarding
the callbacks use of that library var oldConsole = window.console; window.console
= console; try { fn(console); } catch (e) { if (typeof onuncaughtException !== 'undefined')
{ //probably window.onuncaughtError but maybe not. you can var over it onuncaughtException(e);
//this function can choose to re-throw or not, anyone's choice } else { console.warn(
'You should define a window.onuncaughtException handler for exceptions,' + ' or use
a library like Sheild.js' ); throw e; } } finally { //finally block so we can restore
window.console even if we re-throw an error window.console = oldConsole; } }; }
<script>
Benchmark.prototype.setup = function() {
//some real code!
function historicalConsole(fn, optionalName) {
if (optionalName && historicalConsole[optionalName]) {
//names not supported quite yet
//return historicalConsole[optionalName];
}
//validate callback:
if (Object.prototype.toString.call(fn) != '[object Function]' || arguments.length !== 1 || fn.length !== 1) {
var message = 'historicalConsole expects one function argument like this: ' + 'historicalConsole(function(console){/*your whole program*/});';
alert(message);
console.error(message + ' You passed in these arguments: ', arguments);
return;
}
//returning a function allows for more flexible use of `historicalConsole`
return function historicalConsoleClosure() {
if (arguments.length > 0) {
console.warn('The function returned from historicalConsole does not take arguments. ' + 'These arguments will be ignored. You\'re probably doing something wrong');
}
//override global console temporarily so that console.* calls from externals
//are logged too. This could be developer feedback from external libraries
//regarding the callbacks use of that library
var oldConsole = window.console;
window.console = console;
try {
fn(console);
} catch (e) {
if (typeof onuncaughtException !== 'undefined') { //probably window.onuncaughtError but maybe not. you can var over it
onuncaughtException(e); //this function can choose to re-throw or not, anyone's choice
} else {
console.warn('You should define a window.onuncaughtException handler for exceptions,' + ' or use a library like Sheild.js');
throw e;
}
} finally { //finally block so we can restore window.console even if we re-throw an error
window.console = oldConsole;
}
};
}
};
Benchmark.prototype.teardown = function() {
historicalConsole.prototype = {};
for (var method in historicalConsole) {
if (historicalConsole.hasOwnProperty(method)) {
historicalConsole[method] = null;
}
}
};
</script>
Preparation code output
//some real code! function historicalConsole(fn, optionalName) { if (optionalName
&& historicalConsole[optionalName]) { //names not supported quite yet //return historicalConsole[optionalName];
} //validate callback: if (Object.prototype.toString.call(fn) != '[object Function]'
|| arguments.length !== 1 || fn.length !== 1) { var message = 'historicalConsole
expects one function argument like this: ' + 'historicalConsole(function(console){/*your
whole program*/});'; alert(message); console.error(message + ' You passed in these
arguments: ', arguments); return; } //returning a function allows for more flexible
use of `historicalConsole` return function historicalConsoleClosure() { if (arguments.length
> 0) { console.warn( 'The function returned from historicalConsole does not take
arguments. ' + 'These arguments will be ignored. You\'re probably doing something
wrong' ); } //override global console temporarily so that console.* calls from externals
//are logged too. This could be developer feedback from external libraries //regarding
the callbacks use of that library var oldConsole = window.console; window.console
= console; try { fn(console); } catch (e) { if (typeof onuncaughtException !== 'undefined')
{ //probably window.onuncaughtError but maybe not. you can var over it onuncaughtException(e);
//this function can choose to re-throw or not, anyone's choice } else { console.warn(
'You should define a window.onuncaughtException handler for exceptions,' + ' or use
a library like Sheild.js' ); throw e; } } finally { //finally block so we can restore
window.console even if we re-throw an error window.console = oldConsole; } }; }
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
proto |
|
pending… |
props |
|
pending… |
You can edit these tests or add even more tests to this page by appending /edit to the URL.
0 comments