Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the for() function faster than ES6 map() and some() for finding duplicates? [duplicate]

I wanted to benchmark the function that I am using to find out if there is a duplicated attribute in an array of objects using map() and some() versus another function that does the same thing but using a for() inside another for().

let array = [ { "value": 41}, { "value": 12}, { "value": 32} ];

let itens = array.map(x => x.value);

let haveDuplicate = itens.some((item, idx) => itens.indexOf(item) !== idx);

versus:

let array = [ { "value": 41}, { "value": 12}, { "value": 32} ];

let haveDuplicate = false;

for (let i = 0; i < array.length; i++) {
    let x = array[i];
    for (let j = (i + 1); j < array.length; j++) {
        if (array[j]) {
            let y = array[j];
            if (x.value === y.value) {
                haveDuplicate = true;
                return;
            } else {
                haveDuplicate = false;
            }
        }
    }
}

Using JsPerf I can see that the function that uses map() and some() runs 90% ~ 100% slower. Click here to check the benchmark

Can someone explain to me why?

EDIT: this question is duplicate of this one: Why most JavaScript native functions are slower than their naive implementations?

like image 623
Cassiano Montanari Avatar asked Apr 06 '18 01:04

Cassiano Montanari


1 Answers

There are few reasons the loop version is faster.

  1. The .map version can have overhead of calling functions, which requires allocate memory, push to stack, some runtime checking the function is callable, etc. It may get optimized, or not.

  2. The code are not equivalent. .indexOf need to scan the whole array if item does not exist where as the for loop version the second loop does not always scan the whole array.


Also, you better to use Set (or just object incase Set is not available) to do the duplicate check.

Pick the right data structure/algorithm is usually the most important optimization step.

let itens = array.map(x => x.value);

haveDuplicate = new Set(itens).size !== itens.length
like image 184
Bryan Chen Avatar answered Oct 31 '22 04:10

Bryan Chen