Why using for is faster than some() or filter()

前端 未结 3 1008
余生分开走
余生分开走 2021-01-14 01:20

I tried two different way to do something and I am surprised by the performance result :

I have 2 versions of a function :

Using a for :

相关标签:
3条回答
  • 2021-01-14 01:53

    Given the article you posted in the comments (and the associated benchmarks), we can safely conclude that the massive difference you are noticing is because the benchmarks you're looking at are not great.

    • The benchmarks aren't programmed equal. The loop example uses console.timeEnd and console.log, both of which are notoriously inefficient.
    • The some example performs type coercion.
    • All of the tests are performing string concatenation within their loops. This doesn't necessarily impact the fairness of the benchmarks but it does mean you are testing string concatenation and the access methods.

    Now, with an array of 300 items and 300 iterations, the results when these factors are eliminated on a 8GB DDR3 Intel i5 Laptop on Chrome 44 are as follows (re-ordered in terms of slowest to fastest):

    OBJECT Average 0.0010666643114139636
    SEEK Average 0.00593666957380871
    LOOP Average 0.008436664550875625
    SOME Average 0.013993332007279
    FILTER Average 0.02592999837361276
    

    These are what is to be expected, and here is why:

    Seek

    Seek is implemented as using indexOf to locate an element and then accessing that element at the direct array index. The actual method of determining whether something equates to a value is implemented by the browser so I don't know how this method works exactly but one would assume it is essentially a browser-implemented, optimized version of some.

    Loop

    The loop approach is slower primarily because unlike the 'seek' test, the loop test iterates over the entire array and does both array access AND object access. The seek method doesn't do this. It breaks out almost immediately after finding the element. I don't know if this would quite explain the discrepancy between seek and loop, though I would not be surprised. Again, though, seek is browser-implemented and thus able to be optimized - the loop could be optimized but you still have to offset for the fact that it can be optimized less than seek.

    Some

    Some has the overhead of a function invocation to be invoked every single iteration. In addition, this cannot be optimized at all by the JIT compiler because the JIT compiler doesn't know what you're going to pass into some.

    Filter

    Filter iterates the entire array before returning, so this shouldn't really be a surprise.

    Object access

    In Chrome at least, object access is blazingly fast because of the way objects are compiled under the hood to classes. Its worth mentioning that all arrays are objects and so use the same method.

    The long and short of it is that these benchmarks are testing far more than just the behaviour of some and a for loop, making their value dubious.

    0 讨论(0)
  • 2021-01-14 01:53

    Nothing beats native (vanilla) javascript when it comes to performance. Question boils down to "Do you want to spend time and resources in re-inventing the wheel by doing it yourself or just leveraging an external lib that does it for you?". Yes you sacrifice load time and performance but you save time and time is money. You can make your for loop faster by also caching the length of the array as such

    for (var i = 0, len = $scope.filteredCartoList.length; i < len; i++)

    This is going to work faster especially in IE because here you are caching the length of your $scope.filteredCartoList instead of calculating it every iteration of the loop.

    0 讨论(0)
  • 2021-01-14 01:57

    Consider these two examples:

    for (var i = 0; i < array.length; i++) {
        doThing(array[i]);
    }
    

    vs.

    function processItem(item) {
        doThing(item);
    }
    for (var i = 0; i < array.length; i++) {
        processItem(array[i]);
    }
    

    This is basically the difference between the two. There also has to be some logic inside of filter and some for handling the return value from processItem but basically you're stacking a whole extra function call on top of your loop.

    0 讨论(0)
提交回复
热议问题