Look at what's happening differently in each iteration:
for( var i = 0; i < p1.length; i++ )
- Check if
i < p1.length - Increment
iby one
Very simple and fast.
Now look at what's happening in each iteration for this:
for( var i in p1 )
Repeat
- Let P be the name of the next property of obj whose [[Enumerable]] attribute is true. If there is no such property, return (normal, V, empty).
It has to find next property in the object that is enumerable. With your array you know that this can be achieved by a simple integer increment, where as the algorithm to find next enumerable is most likely not that simple because it has to work on arbitrary object and its prototype chain keys.
Answer from Esailija on Stack OverflowWhenever i loop through an array i personally prefer to use array.foreach to apply something to whatever element i wish to edit, but the industry standard seems to be using for loops. Is this becasue the industry isnt fully used to ES6 notation or is either method good in its respective ways? Anyways which method do you prefer to use, and why?
If you want to do sequential async tasks, you can't use forEach, you need to use a for loop with await.
Foreach, Map, Reduce, Filter, for..of, all these are good.
Now there are some cases where for..of or for loop will be substantially faster than a foreach for example, mainly because of the overhead caused by the callback in the foreach. But these are extreme cases, pretty rare, involving a high amount of elements being looped through.
In these cases you should always do some benchmark with different options to analyse the results and pick the best one anyway.
I prefer to use the aggregate functions over for loops because they're more expressive in my eyes. It's purely subjective though, and all the other options are fine too.
Javascript for..in vs for loop performance - Stack Overflow
For-Of Loop vs. For Loop - javascript
Why is for...of loop so much slower than the traditional for loop?
java - Is there a performance difference between a for loop and a for-each loop? - Stack Overflow
Videos
Look at what's happening differently in each iteration:
for( var i = 0; i < p1.length; i++ )
- Check if
i < p1.length - Increment
iby one
Very simple and fast.
Now look at what's happening in each iteration for this:
for( var i in p1 )
Repeat
- Let P be the name of the next property of obj whose [[Enumerable]] attribute is true. If there is no such property, return (normal, V, empty).
It has to find next property in the object that is enumerable. With your array you know that this can be achieved by a simple integer increment, where as the algorithm to find next enumerable is most likely not that simple because it has to work on arbitrary object and its prototype chain keys.
As a side note, if you cache the length of p1:
var plen = p1.length;
for( var i = 0; i < plen; i++ )
you will get a slight speed increase.
...And if you memoize the function, it will cache results, so if the user tries the same numbers you will see a massive speed increase.
var eDistance = memoize(euclideanDistance);
function memoize( fn ) {
return function () {
var args = Array.prototype.slice.call(arguments),
hash = "",
i = args.length;
currentArg = null;
while (i--) {
currentArg = args[i];
hash += (currentArg === Object(currentArg)) ?
JSON.stringify(currentArg) : currentArg;
fn.memoize || (fn.memoize = {});
}
return (hash in fn.memoize) ? fn.memoize[hash] :
fn.memoize[hash] = fn.apply(this, args);
};
}
eDistance([1,2,3],[1,2,3]);
eDistance([1,2,3],[1,2,3]); //Returns cached value
credit: http://addyosmani.com/blog/faster-javascript-memoization/
A bit of backnowledge to explain your question:
In Javascript, Objects (among these are Arrays) store properties in key-value pairs. That means that each assigned value has a key (the property name) to access it. For example in
person[name] = 'Tom'
person is the Object, name the key and 'Tom' the corresponding value.
Arrays use indices (i.e. numbers) as keys:
array[5] = 10
Now, keep that in mind in the following explanation.
Let's start with the traditional for loop:
for(let i = 0; i < array.length; i++) {...}
This way of iterating over an array is the oldest of the bunch (as long as you are not using while-loops)
You'll find a corresponding way of writing a for loop in pretty much any (imperative) programming language. You'll notice, it is very explicit in the way it works. E.g. you could change the break-condition i < array.length to something else (e.g. i < array.length-1 for skipping the last position), or the step i++ (e.g. to i+=2), or start at a different index (e.g. let i = 5). You can iterate backwards instead of forwards through the array, if you want. Pretty much anything you can do in another for loop, you can do in this kind as well, if you know how.
Inside the brackets {...} you can then use i as a key to access the arrays values
Now this is all very powerful and nice, but it gets cumbersome to write every time, especially if in most of the cases you just want to iterate over an array. But luckily we have for-in:
For-in will retrieve you all the keys you have set yourself. With an array, you can use that to achieve the same result as above using
for(let i in array) {...}
Note however, that for-in is not only gonna give you the number keys from an array. It is also gonna work on other keys you have set yourself on any object:
let object = {
key1 : 'value',
key2 : 'value'
}
for(let i in object) {
console.log(i)
}
will log out 'key1' and 'key2' (yes, the keys as well are strings here).
For a bit more precise description of what keys exactly it will give you, have a look at the link below.
When would you use for-in? Whenever you want to call some code for each element of an array / (almost) each property of an object once. E.g. when you want to increment all values in an array by 1. When not to use for-in? Don't use it if you need more granular control over the order you traverse the array in, or you don't want to hit all elements of the array, but only every second/third.
For an excellent resource on for-in loops I recommend Mozilla Developer Network
So, what are for-of loops then?
For-of loops are syntactically (i.e. the way you write them) very similar to for-in loops:
for(let v of array) {...}
However, for one, they are only going to work on so-called iterable objects (arrays are iterable). Second, you only get the values. They are no longer going to give you any keys!
let array = ['a', 'b', 'c']
for(let v of array) {
console.log(v)
}
logs 'a', 'b' and 'c'. You won't know anymore, what keys these values had!
So, when to use these? Every time you just need the values and don't care about the keys. E.g. if you just want to print the values. When not to use them? If you want to swap elements of an array, if you want to reverse order. You can't even increment the values by 1 and store them back into the array, because for that, you would need to know their corresponding key.
For more information on for-in loops as well as what iterable actually means, again, I recommend the MDN
The only key differences that you'll have to consider would be
Say you want to start your loop from a specific index, you can do that with your traditional for loop but not using
for...of.You can't access indices of your array elements natively. You'll need to go for a workaround to achieve this.
//Cannot access indices for(const num of [11,22,33,44,55]){ console.log(num); } //Workaround for(const [index, num] of [11,22,33,44,55].entries()){ console.log(num, index); }
From Item 46 in Effective Java by Joshua Bloch :
The for-each loop, introduced in release 1.5, gets rid of the clutter and the opportunity for error by hiding the iterator or index variable completely. The resulting idiom applies equally to collections and arrays:
// The preferred idiom for iterating over collections and arrays for (Element e : elements) { doSomething(e); }When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” Note that there is no performance penalty for using the for-each loop, even for arrays. In fact, it may offer a slight performance advantage over an ordinary for loop in some circumstances, as it computes the limit of the array index only once. While you can do this by hand (Item 45), programmers don’t always do so.
All these loops do the exact same, I just want to show these before throwing in my two cents.
First, the classic way of looping through List:
for (int i=0; i < strings.size(); i++) { /* do something using strings.get(i) */ }
Second, the preferred way since it's less error prone (how many times have YOU done the "oops, mixed the variables i and j in these loops within loops" thing?).
for (String s : strings) { /* do something using s */ }
Third, the micro-optimized for loop:
int size = strings.size();
for (int i = -1; ++i < size;) { /* do something using strings.get(i) */ }
Now the actual two cents: At least when I was testing these, the third one was the fastest when counting milliseconds on how long it took for each type of loop with a simple operation in it repeated a few million times - this was using Java 5 with jre1.6u10 on Windows in case anyone is interested.
While it at least seems to be so that the third one is the fastest, you really should ask yourself if you want to take the risk of implementing this peephole optimization everywhere in your looping code since from what I've seen, actual looping isn't usually the most time consuming part of any real program (or maybe I'm just working on the wrong field, who knows). And also like I mentioned in the pretext for the Java for-each loop (some refer to it as Iterator loop and others as for-in loop) you are less likely to hit that one particular stupid bug when using it. And before debating how this even can even be faster than the other ones, remember that javac doesn't optimize bytecode at all (well, nearly at all anyway), it just compiles it.
If you're into micro-optimization though and/or your software uses lots of recursive loops and such then you may be interested in the third loop type. Just remember to benchmark your software well both before and after changing the for loops you have to this odd, micro-optimized one.
I recommend to always use for … of in ES6.
- It works on any iterable.
- It supports all kinds of control flow in the loop body, like
continue,break,return,yieldandawait.
Also I personally find it more readable, but that comes down to preference. Some people think forEach is a more functional style, but that's wrong – it has no result value and is all about doing side effects, so an imperative-looking loop fits that purpose better.
Performance is not a concern: in modern engines all loop styles are equivalent.
This is a very interesting question which has been discussed in many other sites. I'll post the basics of what I have read.
ForEach exclusively belong to the royal family of Arrays. The forEach method was introduced with lineage to the prototypal inheritance of Array object! Needless to say, the forEach clause works only with those data structure which are Arrays. The method basically iterates over the elements of the array and executes a callback function [basically some executable function/ fun activity].
The for-of loop is adequately new to the JS world and packs in super-powers! Voilaaaaaaa! The for-of loop creates a loop iterating over iterable member objects. The list is an extensive one such as
- Array
- Map
- Set
- String
- TypedArray
- Other W3C classes
You need to know that this bad-ass boy emerged with the birth of ES6 in 2015. So, it offers plenty of flexibility in usage
Performance
In performance, for...of is faster than forEach. Results can be found here
forEach is 24% slower than for...of
Update
There are several other iterable classes in the W3C specification, like FileList, as I mentioned above. And in recent drafts of W3C (around when ES6 was released), collections like HTMLCollection and NodeList now implement forEach() as well, not just Array anymore. By @Patrick Roberts
Source Links:
- https://codeburst.io/foreach-vs-for-of-vs-for-in-tug-of-for-d8f935396648
- https://www.reddit.com/r/javascript/comments/4spd5b/forof_vs_foreach/
That clearly depends on the particular implementation of the interpreter/compiler of the specific language.
That said, theoretically, any sane implementation is likely to be able to implement one in terms of the other if it was faster so the difference should be negligible at most.
Of course, I assumed while and for behave as they do in C and similar languages. You could create a language with completely different semantics for while and for
In C#, the For loop is slightly faster.
For loop average about 2.95 to 3.02 ms.
The While loop averaged about 3.05 to 3.37 ms.
Quick little console app to prove:
class Program
{
static void Main(string[] args)
{
int max = 1000000000;
Stopwatch stopWatch = new Stopwatch();
if (args.Length == 1 && args[0].ToString() == "While")
{
Console.WriteLine("While Loop: ");
stopWatch.Start();
WhileLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
else
{
Console.WriteLine("For Loop: ");
stopWatch.Start();
ForLoop(max);
stopWatch.Stop();
DisplayElapsedTime(stopWatch.Elapsed);
}
}
private static void WhileLoop(int max)
{
int i = 0;
while (i <= max)
{
//Console.WriteLine(i);
i++;
};
}
private static void ForLoop(int max)
{
for (int i = 0; i <= max; i++)
{
//Console.WriteLine(i);
}
}
private static void DisplayElapsedTime(TimeSpan ts)
{
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
}
}
From section 14.14.2 of the JLS:
Otherwise, the Expression necessarily has an array type, T[]. Let L1 ... Lm be the (possibly empty) sequence of labels immediately preceding the enhanced for statement. Then the meaning of the enhanced for statement is given by the following basic for statement:
T[] a = Expression; L1: L2: ... Lm: for (int i = 0; i < a.length; i++) { VariableModifiersopt Type Identifier = a[i]; Statement }
In other words, I'd expect them to end up being compiled to the same code.
There's definitely a clear winner: the enhanced for loop is more readable. That should be your primary concern - you should only even consider micro-optimizing this sort of thing when you've proved that the most readable form doesn't perform as well as you want.
You can write your own simple test, which measure the execution time.
long start = System.currentTimeMillis();
forLoop(text);
long end = System.currentTimeMillis();
long result = end - start;
result is execution time.
Patrick Smacchia blogged about this last month, with the following conclusions:
forloops onList<T>are a bit more than 2 times cheaper thanforeachloops onList<T>.- Looping on array is around 2 times cheaper than looping on
List<T>.- As a consequence, looping on array using
foris 5 times cheaper than looping onList<T>usingforeach(which I believe, is what we all do).
First, a counter-claim to Dmitry's (now deleted) answer. For arrays, the C# compiler emits largely the same code for foreach as it would for an equivalent for loop. That explains why for this benchmark, the results are basically the same:
using System;
using System.Diagnostics;
using System.Linq;
class Test
{
const int Size = 1000000;
const int Iterations = 10000;
static void Main()
{
double[] data = new double[Size];
Random rng = new Random();
for (int i=0; i < data.Length; i++)
{
data[i] = rng.NextDouble();
}
double correctSum = data.Sum();
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
double sum = 0;
for (int j=0; j < data.Length; j++)
{
sum += data[j];
}
if (Math.Abs(sum-correctSum) > 0.1)
{
Console.WriteLine("Summation failed");
return;
}
}
sw.Stop();
Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int i=0; i < Iterations; i++)
{
double sum = 0;
foreach (double d in data)
{
sum += d;
}
if (Math.Abs(sum-correctSum) > 0.1)
{
Console.WriteLine("Summation failed");
return;
}
}
sw.Stop();
Console.WriteLine("Foreach loop: {0}", sw.ElapsedMilliseconds);
}
}
Results:
For loop: 16638
Foreach loop: 16529
Next, validation that Greg's point about the collection type being important - change the array to a List<double> in the above, and you get radically different results. Not only is it significantly slower in general, but foreach becomes significantly slower than accessing by index. Having said that, I would still almost always prefer foreach to a for loop where it makes the code simpler - because readability is almost always important, whereas micro-optimisation rarely is.