Just wrote up some test cases in jsperf to test the difference between named and anonymous functions while using Array.map
and other alternatives.
http://jsperf.com/map-reduce-named-functions
(excuse the url name, there is no testing of Array.reduce
in here, I named the test before fully deciding on what I wanted to test)
A simple for/while loop is obviously the fastest, I'm still surprised by the more than 10x slower Array.map
though...
Then I tried the polyfill by mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill
Array.prototype.map = function(fun /*, thisArg */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var res = new Array(len);
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
// NOTE: Absolute correctness would demand Object.defineProperty
// be used. But this method is fairly new, and failure is
// possible only if Object.prototype or Array.prototype
// has a property |i| (very unlikely), so use a less-correct
// but more portable alternative.
if (i in t)
res[i] = fun.call(thisArg, t[i], i, t);
}
return res;
};
Then I tried a simple implementation that I wrote myself...
Array.prototype.map3 = function(callback /*, thisArg */) {
'use strict';
if (typeof callback !== 'function') {
throw new TypeError();
}
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0, len = this.length; i < len; i++) {
this[i] = callback.call(thisArg, this[i], i, this);
};
};
Summary of results:
From fastest to slowest:
Array.map
Observations
An interesting note is that named functions are usually alittle faster than if you use anonymous functions (around 5%). But I noticed that the polyfill is slower with named functions in firefox, but faster in chrome, but chrome's own map implementation is slower with named functions... I tested this about 10x each, so even if it's not exactly intensive testing (which jsperf already does), unless my luck is that great it should be enough as a guideline.
Also, chrome's map
function is up to 2x slower than firefox on my machine. Didn't expect that at all.
And... firefox's own Array.map
implementation is slower than the Mozilla Polyfill... haha
I'm not sure why ECMA-262 specs state that map
can be used for objects other than Arrays (http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19). That makes the whole map function 3-4 times slower (as shown in my tests) as you need to check for property existence every loop...
Conclusion
There isn't really much difference between named and anonymous functions, if you consider that different browsers perform slightly differently.
At the end of the day, we shouldn't really micro-optimize too much, but I found this interesting :)
map() works way faster than for loop.
map() takes about 2,000ms, whereas a for loop takes about 250ms.
numeric keys random(). toString() . The results are similar to those string-key cases: Map s start off as much faster than objects (2 times faster for insertion and deletion, 4-5 times faster for iteration), but the delta is getting smaller as we increase the size.
When I modify the tests to actually do the same thing, map is faster than foreach. I would argue it is scientific when used for the case of "I need to do something to each array element, what should I use?" question.
Well first of all, it's not a fair comparison. As you said, the proper javascript map is able to use objects, not just arrays. So you are basically comparing two completely different functions with different algorithms/results/inner workings.
Of course the proper javascript map is slower - it is designed to work over a larger domain than a simple for over an array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With