问题
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:
- For simple/while (about the same)
- Map3 (my own implementation)
- Map2 (Mozilla polyfill)
Array.map
- for in
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 :)
回答1:
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.
来源:https://stackoverflow.com/questions/22182454/javascript-performance-of-array-map