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
andcontinue
) - condition control (
i<n
can be anything and not bound to an array's size) - variable scoping (
var i
leavesi
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 calledval
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
- Set the index variable to its initial value
- Check whether or not to exit the loop
- Run the body of your loop
- Increment the index variable
- 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
- Instantiate the callback function
- Check if there's a next element to process
- 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)
- Run the contents of your callback
- Teardown of callback function call
- 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...
.forEach vs Object.keys().forEach performance on sparse arrays
as ifbecause, in one case, a giant pointless loop from zero to lengthwould beis executed, but not in the other case.
According to the ECMA documentation:
- The
.forEach
method will loop through all array elements by its.length
property. - 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
Clean Way to Programmatically Use CSS Transitions from Js
Center an Image Vertically and Horizontally Using CSS
Good Reasons Why Not to Use Iframes in Page Content
IE9: Why Setting "-Ms-Transform" Works from CSS, But Not with Jquery.Css()
How to Combine Jquery Animate with CSS3 Properties Without Using CSS Transitions
Browsers Automatically Evaluate Hex or Hsl Colors to Rgb When Setting via Element.Style.Background
How to Animate the Drawing of Text on a Web Page
"Status Code:200 Ok (From Serviceworker)" in Chrome Network Devtools
Html5 Drag & Drop Change Icon/Cursor While Dragging
Jquery Add Class Based on Page Url
Convert JavaScript-Generated Svg to a File
:Touch CSS Pseudo-Class or Something Similar