Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript performance of Array.map

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 :)

like image 376
Populus Avatar asked Mar 04 '14 20:03

Populus


People also ask

Is array map faster than for loop?

map() works way faster than for loop.

How fast is Javascript map?

map() takes about 2,000ms, whereas a for loop takes about 250ms.

Are maps faster than objects Javascript?

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.

Is map slower than forEach?

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.


1 Answers

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.

like image 107
or29544 Avatar answered Sep 21 '22 15:09

or29544