[js] Comparison of array traversal performance of for, forEach, and map

[js] Comparison of array traversal performance of for, forEach, and map

First, the results: in terms of traversal time, for loop traversal < for...of traversal < forEach traversal < for...in traversal < map traversal

background

There are many commonly used array traversal methods,
such as the most classic for loop

    for (var i = 0; i < arr.length; i++) {
    
    }

Moreover, there is for…in

    for (var i in arr) {
    
    }

forEach

    arr.forEach(function (i) {
    
    });

map

    arr.map(function (i) {
    
    });

Then ES6 has a more convenient for...of

    for (let i of arr) {
    
    }

This article does not consider the differences in functions, but only makes a comparison of the performance of these methods.

Note: filter, every, and some are similar to forEach/map and are not commonly used, so they are not included in the comparison this time.

1. Comparison plan

This time we use the most intuitive way to compare: by comparing the traversal time of high-order arrays.

1.1 Array arr:

    let arr = [];
    for (let i = 0; i < 10000000; i++) {
    
    
        arr[i] = i;
    }

    console.log(arr);   // [0, 1, 2, 3, ... , 9999999]

1.2 Comparison function:

    function getAverageTime (cb) {
    
    
        let _start = +new Date();

        for (let k = 0; k < 20; k++) {
    
    
            cb();   //  遍历函数
        }

        return (+new Date() - _start) / 20 + 'ms'
    }
  • where cb is the traversal function.
    We calculate the traversal time by averaging 20 times as a basis for comparison.

2. Compare

1.1 Classic for loop traversal

    getAverageTime(function () {
    
    
        for (let i = 0; i < arr.length; i++) {
    
    
            let item = arr[i];
            // ...
        }
    })

Result:
6.3ms

for loop

1.2 for…in traversal

    getAverageTime(function () {
    
    
        for (let i in arr) {
    
    
            let item = arr[i];
            // ...
        }
    })

Result:
1539.45ms

sorry

1.3 forEach traversal

    getAverageTime(function () {
    
    
        arr.forEach(item => {
    
    })
    })

Result:
190.75ms

foreach

1.4 map traversal

    getAverageTime(function () {
    
    
        arr.map(item => {
    
    })
    })

Result:
2014.65ms

map

1.5 for…of traversal

    getAverageTime(function () {
    
    
        for (let item of arr) {
    
    
            // ...
        }
    })

Result:
129.5ms

forof

*Traverse after converting babel to ES5

for...of is ES6 syntax, so babel conversion is basically done in daily pages, so you need to test the traversal after conversion.

    getAverageTime(function () {
    
    
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;

        try {
    
    
          for (var _iterator = arr[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    
    
            //...

            var item = _step.value;
          }
        } catch (err) {
    
    
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
    
    
          try {
    
    
            if (!_iteratorNormalCompletion && _iterator.return) {
    
    
              _iterator.return();
            }
          } finally {
    
    
            if (_didIteratorError) {
    
    
              throw _iteratorError;
            }
          }
        }
    });

Result:
105.9ms
forofbabel

(Do you feel that the code converted by for...of after Babel is very weird? If you are interested, you can learn about the Symbol object . In fact, the Symbol object is also newly added to ES6, but the compatibility is better than for...of. If you want to be compatible with lower version mobile phones, learn more es -symbol )

3 Result analysis

By comparison, it can be seen that the traversal time

    for循环遍历 < for...of遍历 < forEach遍历 < for...in遍历 < map遍历

3.1 *Why is for...in slow?

Because the for ... in syntax was the first JavaScript statement to be able to iterate over object keys, looping over object keys ({}) is different from looping over an array ([]), and the engine does some extra work to keep track of which properties have been iterated over.

Therefore, we can roughly draw the following points:

  • When the amount of data is large, the gap in traversal performance is particularly obvious;
  • The overall performance of for system traversal is better than array methods such as forEach and map.
  • Your uncle is your uncle after all. The best performance is the classic for loop traversal
  • forEach performs better than map
  • For...of If you want to be compatible with lower version devices, forget it.

The performance of traversal can be used as a reference for future development. After all, the difference is negligible when the amount of data is small. The traversal method can be considered based on the actual effect. For example, for traversal can break and exit midway, but forEach/map cannot.

*Attach a traversal abstract function that considers variable types
/**
 * @param {Object | Array} array
 * @param {Function} func
 */
function eachPlus (array, func) {
    
    
    if (!array) {
    
    
        return;
    }
    
    let rst = void 0,
        type = Object.prototype.toString.call(array).replace(/\[object\s|\]/g, '');
    if (type === 'Array') {
    
    
        for (let i = 0, len = array.length; i < len; i++) {
    
    
            rst = func(array[i], i);
            if (rst === false) {
    
    	// 实现break中断
                break;
            }
        }
    } else if (type  === 'Object') {
    
    
        for (let k in array) {
    
    
            if (array.hasOwnProperty(k)) {
    
    
                rst = func(array[k], k);
                if (rst === false) {
    
    
                    break;
                }
            }
        }
    }
}

// demo
eachPlus([1, 2, 3], item => {
    
    
	console.log(item);
})
eachPlue({
    
     a: 1, b: 2, c: 3 }, item => {
    
    
	console.log(item);
})

Text blog address
If you have suggestions or want to break eggs -> [email protected]

Guess you like

Origin blog.csdn.net/qq_24357165/article/details/82748976