Which one is faster? Why?
var messages:Array = [.....]
// 1 - for
var len:int = messages.length;
for (var i:int = 0; i < len; i++) {
var o:Object = messages[i];
// ...
}
// 2 - foreach
for each (var o:Object in messages) {
// ...
}
From where I'm sitting, regular for loops are moderately faster than for each loops in the minimal case. Also, as with AS2 days, decrementing your way through a for loop generally provides a very minor improvement.
But really, any slight difference here will be dwarfed by the requirements of what you actually do inside the loop. You can find operations that will work faster or slower in either case. The real answer is that neither kind of loop can be meaningfully said to be faster than the other - you must profile your code as it appears in your application.
Sample code:
var size:Number = 10000000;
var arr:Array = [];
for (var i:int=0; i<size; i++) { arr[i] = i; }
var time:Number, o:Object;
// for()
time = getTimer();
for (i=0; i<size; i++) { arr[i]; }
trace("for test: "+(getTimer()-time)+"ms");
// for() reversed
time = getTimer();
for (i=size-1; i>=0; i--) { arr[i]; }
trace("for reversed test: "+(getTimer()-time)+"ms");
// for..in
time = getTimer();
for each(o in arr) { o; }
trace("for each test: "+(getTimer()-time)+"ms");
Results:
for test: 124ms
for reversed test: 110ms
for each test: 261ms
Edit: To improve the comparison, I changed the inner loops so they do nothing but access the collection value.
Edit 2: Answers to oshyshko's comment:
The compiler could skip the accesses in my internal loops, but it doesn't. The loops would exit two or three times faster if it was.
The results change in the sample code you posted because in that version, the for loop now has an implicit type conversion. I left assignments out of my loops to avoid that.
Of course one could argue that it's okay to have an extra cast in the for loop because "real code" would need it anyway, but to me that's just another way of saying "there's no general answer; which loop is faster depends on what you do inside your loop". Which is the answer I'm giving you. ;)
When iterating over an array, for each loops are way faster in my tests.
var len:int = 1000000;
var i:int = 0;
var arr:Array = [];
while(i < len) {
arr[i] = i;
i++;
}
function forEachLoop():void {
var t:Number = getTimer();
var sum:Number = 0;
for each(var num:Number in arr) {
sum += num;
}
trace("forEachLoop :", (getTimer() - t));
}
function whileLoop():void {
var t:Number = getTimer();
var sum:Number = 0;
var i:int = 0;
while(i < len) {
sum += arr[i] as Number;
i++;
}
trace("whileLoop :", (getTimer() - t));
}
forEachLoop();
whileLoop();
This gives:
forEachLoop : 87
whileLoop : 967
Here, probably most of while loop time is spent casting the array item to a Number. However, I consider it a fair comparison, since that's what you get in the for each loop.
My guess is that this difference has to do with the fact that, as mentioned, the as operator is relatively expensive and array access is also relatively slow. With a for each loop, both operations are handled natively, I think, as opossed to performed in Actionscript.
Note, however, that if type conversion actually takes place, the for each version is much slower and the while version if noticeably faster (though, still, for each beats while):
To test, change array initialization to this:
while(i < len) {
arr[i] = i + "";
i++;
}
And now the results are:
forEachLoop : 328
whileLoop : 366
forEachLoop : 324
whileLoop : 369
I've had this discussion with a few collegues before, and we have all found different results for different scenarios. However, there was one test that I found quite eloquent for comparison's sake:
var array:Array=new Array();
for (var k:uint=0; k<1000000; k++) {
array.push(Math.random());
}
stage.addEventListener("mouseDown",foreachloop);
stage.addEventListener("mouseUp",forloop);
/////// Array /////
/* 49ms */
function foreachloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var i:uint=0;
for each (var n:Number in array) {
i++;
tmp+=n;
}
trace("foreach", i, tmp, getTimer() - t1);
}
/***** 81ms ****/
function forloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var l:uint=array.length;
for(var i:uint = 0; i < l; i++)
tmp += Number(array[i]);
trace("for", i, tmp, getTimer() - t1);
}
What I like about this tests is that you have a reference for both the key and value in each iteration of both loops (removing the key counter in the "for-each" loop is not that relevant). Also, it operates with Number, which is probably the most common loop that you will want to optimize that much. And most importantly, the winner is the "for-each", which is my favorite loop :P
Notes:
-Referencing the array in a local variable within the function of the "for-each" loop is irrelevant, but in the "for" loop you do get a speed bump (75ms instead of 105ms):
function forloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var a:Array=array;
var l:uint=a.length;
for(var i:uint = 0; i < l; i++)
tmp += Number(a[i]);
trace("for", i, tmp, getTimer() - t1);
}
-If you run the same tests with the Vector class, the results are a bit confusing :S
for would be faster for arrays...but depending on the situation it can be foreach that is best...see this .net benchmark test.
Personally, I'd use either until I got to the point where it became necessary for me to optimize the code. Premature optimization is wasteful :-)
Maybe in a array where all element are there and start at zero (0 to X) it would be faster to use a for loop. In all other case (sparse array) it can be a LOT faster to use for each.
The reason is the usage of two data structure in the array: Hast table an Debse Array.
Please read my Array analysis using Tamarin source:
http://jpauclair.wordpress.com/2009/12/02/tamarin-part-i-as3-array/
The for loop will check at undefined index where the for each will skip those one jumping to next element in the HastTable
guys!
Especially Juan Pablo Califano.
I've checked your test. The main difference in obtain array item.
If you will put var len : int = 40000;, you will see that 'while' cycle is faster.
But it loses with big counts of array, instead for..each.
Just an add-on:
a for each...in loop doesn't assure You, that the elements in the array/vector gets enumerated in the ORDER THEY ARE STORED in them. (except XMLs)
This IS a vital difference, IMO.
"...Therefore, you should not write code that depends on a for-
each-in or for-in loop’s enumeration order unless you are processing
XML data..." C.Moock
(i hope not to break law stating this one phrase...)
Happy benchmarking.
sorry to prove you guys wrong, but for each is faster. even a lot. except, if you don't want to access the array values, but a) this does not make sense and b) this is not the case here.
as a result of this, i made a detailed post on my super new blog ... :D
greetz
back2dos
Related
So let's consider the case where there is the below snippet:
if(x == 0)
{
for(var i = 0; i < 5; ++ i)
{
//do something
}
}
else
{
for(var i = 0; i < 5; ++ i)
{
//do something different
}
}
As you can see, both of the conditions iterate through the same for loop but perform different actions based on the condition. My question is, is it a bad practice to have something like this:
for(var i = 0; i < 5; ++ i)
{
if(x == 0){
// do something
}else{
// do something else
}
}
The reason being that I think that this may be a bad practice is due to the fact that for every instance of the loop, a conditional check is being executed on it against the first snippet where he condition is checked first and then the loop is executed. Am I mistaken?
Unless you're writing code that must run at high speed and be super efficient, go for code readability over efficiency. In this case, I'd say the 2nd example is clearer as it's less code, and a commonly followed pattern.
I suppose another factor to consider though is that the 2nd example seems to imply that x might change value, whereas the 1st example doesn't. This would be worth putting a comment nearby explaining the choice.
My gut instinct would agree with you, that the 1st example would be more efficient, but in reality the compiler's optimisations are likely to make short work of examples like the above - they'll both likely be equal in performance.
Here's a pretty impressive list of optimisations that can be made on loops, to give you an idea, and also branch optimisation (see the answer), may have an effect if the loops run for many iterations.
If you use
if(x = 0)
{
for(var i = 0; i < 5; ++ i)
{
//do something
}
}
else
{
for(var i = 0; i < 5; ++ i)
{
//do something different
}
}
then you have done one comparison and a loop performing the tasks in the scope for 5 times.
When you use
for(var i =0; i < 5; ++ i)
{
if(x = 0){
// do something
}else{
// do something else
}
}
then a loop performing the tasks in the scope for 5 times. In addition to that, the comparison is done 5 times.
On first sight the former results in least amount of instructions. But the compiler/interpreter may perform an optimization step by doing that comparison one time. But this depend of the compiler/interpreter. If you have a good comprehending of how a compiler/interpreter works for a given language you're programming on, you can "abuse" the knowledge to write a readable code and yet having a well-optimized output.
Yet, another alternative is to work with functions. This approach is only useful if the variable x is constant throughout the loop, with other words: you don't modify it during the loop itself. This is the case at your first example. However, in the second example: x can be changed in the loop, which leads to running either the if {} or else{} block during the loop, executing two different functions.
Alternative: Select a function first and use it in the loop. It may be more useful if you have lots of different tasks to perform. Just select a function beforehand. Some programming languages allows this, another don't. So it depends of the language itself.
// check which function to run
variable runThisFunction;
if (x = 0) runThisFunction = { // do something }
else runThisFunction = { // do something else }
// loop 5 times using the function
for(var i =0; i < 5; ++ i)
{
call runThisFunction with arg i provided.
}
break interrupts a for-loop in most languages, but in the case of nested loops I have never encountered an n-th order break.
1. Is there such a thing in any language?
2. If so what is the correct name for it?
3. If not, why?
NB. I am not looking for workarounds.
Regarding point 3. The closest thing I know is goto, which should not be used as it leads to spaghetti code (Python has it only in a joke module), but this seems like a different problem as a boolean variable to mark an inner break, catching a raised a custom error or moving the block to a function in order to break with return are a lot more convoluted (in terms of line numbers and variables in the code).
(This is a curiosity question from a theoretical point of view, but if it helps, I code primarily in Python, Matlab and JS. I have know Perl, Pascal and Basic, but I know only the basics of C++ and know shamefully little of machine code.)
Java has a labeled break statement that lets you break out of any number of loops:
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search; // <<=== This statement breaks both nested loops
}
}
}
I don't know of any language that lets you do this (apart from #dasblinkenlight example - and not saying there aren't any) but you can easily emulate it in any language that has the break statement.
I.e. conditionnaly break on a boolean exit loop var.
var exitLoops = false;
for (var i = 0; i < x; i++) {
for (var j = 0; j < y; j++) {
for (var k = 0; k < z; k++) {
if (something) {
exitLoops = true;
break;
}
}
if (exitLoops) break;
}
if (exitLoops) break;
}
No there isn't (as far as i know). And why ? because if you need to exit several nested for loops all at once, then you have a code design problem, not a syntax problem. all the answers given above, except of #PinkTurtle , uses some sort of goto statement , which is not recommended .
In JavaScript you can do this
Copy paste the following the Chrome Dev Console,
free:
for(var i=0; i<10; i++) {
for(var j=0; j<10; j++) {
for(var k=0;k<10;k++){
console.log('I am at i='+i+' , j='+j+ ' , k='+k);
if(k==3) {
console.log('I will now break FREE...');
break free;
}
}
}
}
console.log('... And Now I am Here...')
Output
I am at i=0 , j=0 , k=0
I am at i=0 , j=0 , k=1
I am at i=0 , j=0 , k=2
I am at i=0 , j=0 , k=3
I will now break FREE...
... And Now I am Here...
Basically, in this program, I was instructed to create an array of random numbers and then sort them smallest to largest by bubble sorting with for loops. With a bunch of trial and error, my buddy and I were able to figure it out but I just took a look back at my code and honestly, it's very hard to comprehend.. I'm not too familiar with nested loops so if someone could explain how this method is working, that would be awesome. More specifically, what does the value j and i stand for.
public void sort() {
int val = 0;
for(int i = 0; i < myArray.length; i++) {
for(int j = 1; j < (myArray.length - i); j++) {
if(myArray[j-1] > myArray[j]) {
val = myArray[j-1];
myArray[j-1] = myArray[j];
myArray[j] = val;
}
}
}
}
Any answers are greatly appreciated, thanks guys/gals!
i and j are short with no inherent meaning other than to represent the index you are at in the array. The first for loop is so that the second loop and the sorting method are repeated for as many items are in the array. The second loop does the sorting.
if(myArray[j-1] > myArray[j]) { // Checks if the index `j` in the array is less than the one before it.
val = myArray[j-1]; // Temporarily stores the greater value.
myArray[j-1] = myArray[j]; // Swap the numbers.
myArray[j] = val; // Swap the numbers.
}
for (i = 0; i < 10; i++) {
doStuff();
}
That's the JavaScript code that I Want to convert to CoffeeScript.
doStuff() for i in [0 .. 9]
This is explained on the introduction page: http://coffeescript.org/#loops
Edit/Update by JP:
The exact translation is:
doStuff() for i in [0...10]
You need to be careful with the ".." vs "...", for example:
count = 0
doStuff() for i in [0..count] #still executes once!
So you think, no problem... I'll just loop until count-1!
count = 0
doStuff() for i in [0..count-1] #executes twice!! '0' and then '-1'
Literal translation of:
for (var i = 0; i < someCount; ++i)
doStuff()
is
for i in [0...someCount]
doStuff()
The marked answer is functionaly correct but the generated code doesn't match the original javascript.
The right way (read, the one closest to the following javascript)
for (i = 0; i < 10; i++) {
doStuff();
}
is doStuff() for i in [0..someCount] by 1
Note the by 1 on the for loop.
Now this code, still creates an extra _i variable. If you can't live with it, then use the following:
i=0
while i<=someCount
doStuff()
i++
Previous answers work. However, dropping the i generates it better for me:
for [0...10]
doStuff()
or
doStuff() for [0...10]
The other solutions add an extra iterator variable i for you to use inside of the loop, for example doStuff(i), but from http://coffeescript.org/v1/#loops:
If you don’t need the current iteration value you may omit it:
browser.closeCurrentTab() for [0...count]
In detail, the translation of for i in [0...10] is for (i = j = 0; j < 10; i = ++j), whereas the translation of for [0...10] is for (i = 0; i < 10; i++).
Note the discussion in other comments about 2-dots versus 3-dots ([0..9] vs. [0...10]).
The environment: I am working in a proprietary scripting language where there is no such thing as a user-defined function. I have various loops and local variables of primitive types that I can create and use.
I have two related arrays, "times" and "values". They both contain floating point values. I want to numerically sort the "times" array but have to be sure that the same operations are applied on the "values" array. What's the most efficient way I can do this without the benefit of things like recursion?
You could maintain an index table and sort the index table instead.
This way you will not have to worry about times and values being consistent.
And whenever you need a sorted value, you can lookup on the sorted index.
And if in the future you decided there was going to be a third value, the sorting code will not need any changes.
Here's a sample in C#, but it shouldn't be hard to adapt to your scripting language:
static void Main() {
var r = new Random();
// initialize random data
var index = new int[10]; // the index table
var times = new double[10]; // times
var values = new double[10]; // values
for (int i = 0; i < 10; i++) {
index[i] = i;
times[i] = r.NextDouble();
values[i] = r.NextDouble();
}
// a naive bubble sort
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
// compare time value at current index
if (times[index[i]] < times[index[j]]) {
// swap index value (times and values remain unchanged)
var temp = index[i];
index[i] = index[j];
index[j] = temp;
}
// check if the result is correct
for (int i = 0; i < 10; i++)
Console.WriteLine(times[index[i]]);
Console.ReadKey();
}
Note: I used a naive bubble sort there, watchout. In your case, an insertion sort is probably a good candidate. Since you don't want complex recursions.
Just take your favourite sorting algorithm (e.g. Quicksort or Mergesort) and use it to sort the "values" array. Whenever two values are swapped in "values", also swap the values with the same indices in the "times" array.
So basically you can take any fast sorting algorithm and modify the swap() operation so that elements in both arrays are swapped.
Take a look at the Bottom-Up mergesort at Algorithmist. It's a non-recursive way of performing a mergesort. The version presented there uses function calls, but that can be inlined easily enough.
Like martinus said, every time you change a value in one array, do the exact same thing in the parallel array.
Here's a C-like version of a stable-non-recursive mergesort that makes no function calls, and uses no recursion.
const int arrayLength = 40;
float times_array[arrayLength];
float values_array[arrayLength];
// Fill the two arrays....
// Allocate two buffers
float times_buffer[arrayLength];
float values_buffer[arrayLength];
int blockSize = 1;
while (blockSize <= arrayLength)
{
int i = 0;
while (i < arrayLength-blockSize)
{
int begin1 = i;
int end1 = begin1 + blockSize;
int begin2 = end1;
int end2 = begin2 + blockSize;
int bufferIndex = begin1;
while (begin1 < end1 && begin2 < end2)
{
if ( values_array[begin1] > times_array[begin2] )
{
times_buffer[bufferIndex] = times_array[begin2];
values_buffer[bufferIndex++] = values_array[begin2++];
}
else
{
times_buffer[bufferIndex] = times_array[begin1];
values_buffer[bufferIndex++] = values_array[begin1++];
}
}
while ( begin1 < end1 )
{
times_buffer[bufferIndex] = times_array[begin1];
values_buffer[bufferIndex++] = values_array[begin1++];
}
while ( begin2 < end2 )
{
times_buffer[bufferIndex] = times_array[begin2];
values_buffer[bufferIndex++] = values_array[begin2++];
}
for (int k = i; k < i + 2 * blockSize; ++k)
{
times_array[k] = times_buffer[k];
values_array[k] = values_buffer[k];
}
i += 2 * blockSize;
}
blockSize *= 2;
}
I wouldn't suggest writing your own sorting routine, as the sorting routines provided as part of the Java language are well optimized.
The way I'd solve this is to copy the code in the java.util.Arrays class into your own class i.e. org.mydomain.util.Arrays. And add some comments telling yourself not to use the class except when you must have the additional functionality that you're going to add. The Arrays class is quite stable so this is less, less ideal than it would seem, but it's still less than ideal. However, the methods you need to change are private, so you've no real choice.
You then want to create an interface along the lines of:
public static interface SwapHook {
void swap(int a, int b);
}
You then need to add this to the sort method you're going to use, and to every subordinate method called in the sorting procedure, which swaps elements in your primary array. You arrange for the hook to get called by your modified sorting routine, and you can then implement the SortHook interface to achieve the behaviour you want in any secondary (e.g. parallel) arrays.
HTH.