JavaScript Efficiency: 'For' VS 'Foreach'

Javascript efficiency: 'for' vs 'forEach'

for

for loops are much more efficient. It is a looping construct specifically designed to iterate while a condition is true, at the same time offering a stepping mechanism (generally to increase the iterator). Example:

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

This isn't to suggest that for-loops will always be more efficient, just that JS engines and browsers have optimized them to be so. Over the years there have been compromises as to which looping construct is more efficient (for, while, reduce, reverse-while, etc) -- different browsers and JS engines have their own implementations that offer different methodologies to produce the same results. As browsers further optimize to meet performance demands, theoretically [].forEach could be implemented in such a way that it's faster or comparable to a for.

Benefits:

  • efficient
  • early loop termination (honors break and continue)
  • condition control (i<n can be anything and not bound to an array's size)
  • variable scoping (var i leaves i available after the loop ends)

forEach

.forEach are methods that primarily iterate over arrays (also over other enumerable, such as Map and Set objects). They are newer and provide code that is subjectively easier to read. Example:

[].forEach((val, index)=>{
...
});

Benefits:

  • does not involve variable setup (iterates over each element of the array)
  • functions/arrow-functions scope the variable to the block

    In the example above, val would be a parameter of the newly created function. Thus, any variables called val before the loop, would hold their values after it ends.
  • subjectively more maintainable as it may be easier to identify what the code is doing -- it's iterating over an enumerable; whereas a for-loop could be used for any number of looping schemes

Performance

Performance is a tricky topic, which generally requires some experience when it comes to forethought or approach. In order to determine ahead of time (while developing) how much optimization may be required, a programmer must have a good idea of past experience with the problem case, as well as a good understanding of potential solutions.

Using jQuery in some cases may be too slow at times (an experienced developer may know that), whereas other times may be a non-issue, in which case the library's cross-browser compliance and ease of performing other functions (e.g., AJAX, event-handling) would be worth the development (and maintenance) time saved.

Another example is, if performance and optimization was everything, there would be no other code than machine or assembly. Obviously that isn't the case as there are many different high level and low level languages, each with their own tradeoffs. These tradeoffs include, but are not limited to specialization, development ease and speed, maintenance ease and speed, optimized code, error free code, etc.

Approach

If you don't have a good understanding if something will require optimized code, it's generally a good rule of thumb to write maintainable code first. From there, you can test and pinpoint what needs more attention when it's required.

That said, certain obvious optimizations should be part of general practice and not required any thought. For instance, consider the following loop:

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

For each iteration of the loop, JavaScript is retrieving the arr.length, a key-lookup costing operations on each cycle. There is no reason why this shouldn't be:

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

This does the same thing, but only retrieves arr.length once, caching the variable and optimizing your code.

Why Array.forEach is slower than for() loop in Javascript?

Updated based on feedback from @BenAston & @trincot

Roughly, this is what's happening in both cases:

For loop

  1. Set the index variable to its initial value
  2. Check whether or not to exit the loop
  3. Run the body of your loop
  4. Increment the index variable
  5. Back to step 2

The only overhead that happens on every iteration is the check & the increment, which are very low-load operations.

forEach loop

  1. Instantiate the callback function
  2. Check if there's a next element to process
  3. Call the callback for the next element to process, with a new execution context (this comprises the "scope" of the function; so its context, arguments, inner variables, and references to any outer variables -- if used)
  4. Run the contents of your callback
  5. Teardown of callback function call
  6. Return to step 2

The overhead of the function setup & teardown in steps 3 & 5 here are much greater than that of incrementing & checking an integer for the vanilla for-loop.

That said, many modern browsers recognize & optimize forEach calls, and in some cases, the forEach might even be faster!

for loop vs forEach performance in javascript and credibility of jsperf results

I modified your code to be more fair. Can you take a look at it?

var arr = [];for (var i = 0; i < 100000; i++) arr[i] = i;
var numberOfRuns = 100;
function runTest(name, f) { var totalTime = 0; console.time(name);
for (var r = 0; r < numberOfRuns; r++) { f(); }
return console.timeEnd(name);}
function testFunction(v) { v;}
var forTime = runTest('for', function() { for (var j = 0; j < arr.length; j++) { testFunction(arr[j]); }});
var forEachTime = runTest('forEach', function() { arr.forEach(testFunction);});

What's the fastest way to loop through an array in JavaScript?

After performing this test with most modern browsers:
https://jsben.ch/wY5fo

Currently, the fastest form of loop (and in my opinion the most syntactically obvious).

A standard for-loop with length caching

    var i = 0, len = myArray.length;
while (i < len) {
// your code
i++
}

I would say, this is definitely a case where I applaud JavaScript engine developers. A runtime should be optimized for clarity, not cleverness.

Faster loop: foreach vs some (performance of jsperf is different than node or chrome)

After researching a bitI understood what did I do to make jsperf behave in a strange manner. I had the chrome console open when running the jsperf tests

I have seen that when you open the chrome console jsperf still logs console.log and similar messages while the scripts are executing and that is what was causing the misleading result of the tests.

Here you can see the tets after CLOSING the console window...

Sample Image

.forEach vs Object.keys().forEach performance on sparse arrays

as if because, in one case, a giant pointless loop from zero to length would be is executed, but not in the other case.


According to the ECMA documentation:

  1. The .forEach method will loop through all array elements by its .length property.
  2. The callback passed to .forEach will only be invoked if an element is not empty.

To demonstrate this you can simply do:

function doNothing(){}let perf;

console.log('Array with 50 million length and 1 non-empty element:');const a = [];a[49999999] = 'a';console.log('a.length:', a.length);
perf = performance.now();a.forEach(doNothing);console.log('a:', performance.now() - perf);console.log('');

console.log('Array with 0 length:');const b = [];b.foo = 'a';console.log('b.length:', b.length);
perf = performance.now();b.forEach(doNothing);console.log('b:', performance.now() - perf);console.log('');

console.log('Array with 50 million length and 0 non-empty element:');const c = [];c.length = 50000000;console.log('c.length:', c.length);
perf = performance.now();c.forEach(doNothing);console.log('c:', performance.now() - perf);

Array.find vs Array.forEach in performance

The find() method returns the value of the first element in the provided array that satisfies the provided testing function.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Array.find will return the first result that matches the callback condition.

Performance wise they're both O(n), albeit find is likely to cycle through less loops, therefore would be more performent in that respect.

Difference between forEach and for loop in javascript

forEach is a method on the Array prototype. It iterates through each element of an array and passes it to a callback function.

So basically, forEach is a shorthand method for the use-case "pass each element of an array to a function". Here is a common example where I think Array.forEach is quite useful, compared to a for loop:

// shortcut for document.querySelectorAll
function $$(expr, con) {
return Array.prototype.slice.call((con || document).querySelectorAll(expr));
}

// hide an element
function hide(el) {
el.style.display = 'none';
}

// hide all divs via forEach
$$('div').forEach(hide);

// hide all divs via for
for (var divs = $$('div'), i = 0; i < divs.length; i++) {
hide(divs[i])
}

As you can see, the readability of the forEach statement is improved compared to a for loop.

On the other hand, a for statement is more flexible: it does not necessarily involve an array. The performance of a normal for loop is slightly better, because there is no function call for each element involved. Despite of this, it is recommended to avoid for loops when it can be written as a forEach statement.



Related Topics



Leave a reply



Submit