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
:
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.
console.timeEnd
and console.log
, both of which are notoriously inefficient.some
example performs type coercion.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 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
.
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 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 iterates the entire array before returning, so this shouldn't really be a surprise.
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.
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.
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.