Javascript performance of Array.map

隐身守侯 提交于 2019-12-22 01:58:37

问题


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:

  1. For simple/while (about the same)
  2. Map3 (my own implementation)
  3. Map2 (Mozilla polyfill)
  4. Array.map
  5. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!