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.
}
Related
I wanted to know if there's any difference in terms of performance between these two cycles.
I already know they give the same result, but I always see both I'd like to know why does one get picked instead of another.
for (let i = 1; i <= 100; i++) {
//
}
for (let i = 1; i < 101; i++) {
//
}
No, there is no difference between i < 101 and i <= 100. Even if there was, it wouldn't be a difference you could detect.
Rather than worrying about any microoptimizations like this, concern yourself with which makes more sense to the human reader. If you're counting up to 100, then i <= 100 will make more sense to human readers.
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...
Can we make use of function in for loop in c programming language like the below example...
#include <stdio.h>
int main()
{
int i = 0;
for (foo(); i == 1; i = 2)
printf("In for loop\n");
printf("After loop\n");
}
int foo()
{
return 1;
}
Also please explain the output of this code ....Answer --->After loop.
yes you can, so it will return 1 and the loop will never be executed. the loop will be executed if i==1 but i is still 0. This will mean the statement printf("In for loop\n"); is not executed and it will continue after this loop -> printf("After loop\n");
for better understanding you could use brackets surrounding the for loop and indentation.without brackets the for loop includes just the next statement:
for (foo(); i == 1; i = 2){
printf("In for loop\n");
}
printf("After loop\n");
The way you are using for loops does not make a whole lot of sense.
The place where you are calling foo() is where the loop variable usually gets initialized.
Think about the general concepts of for loops:
for (INITIALIZATION; CONDITION; AFTERTHOUGHT)
It would make more sense to write
for (i = foo(); i == 1; i = 2)
I see another problem with your for loop in the AFTERTHOUGHT part.
You usually want to modify the loop variable there, but in a way that it depends on the previous state. In the most simple case just increment it, thus write:
for (i = foo(); i == 1; i++)
Then look at the CONDITION part. It should be true for a range of values, otherwise the loop will terminate quickly (after one iteration in this case). You would maybe want to write something like
for (i = foo(); i <= 3; i++)
to have 3 iterations.
You get the basic idea?
Why PLINQ output is different than sequential processing and Parallel.For loop
I want to add sum of square root of 10,000,000 numbers.. Here is the code for 3 cases:
sequential for loop:
double sum = 0.0;
for(int i = 1;i<10000001;i++)
sum += Math.Sqrt(i);
Output of this is: 21081852648.717
Now Using Parallel.For loop:
object locker = new object();
double total ;
Parallel.For(1,10000001,
()=>0.0,
(i,state,local)=> local+Math.Sqrt(i),
(local)=>
{
lock(locker){ total += local; }
}
);
Output of this is: 21081852648.7199
Now using PLINQ
double tot = ParallelEnumerable.Range(1, 10000000)
.Sum(i => Math.Sqrt(i));
Output of this is: 21081852648.72
Why there is difference between PLINQ output and Parallel.For and Sequential for loop?
I strongly suspect it's because arithmetic with doubles isn't truly associative. Information is potentially lost while summing values, and exactly what information is lost will depend on the order of the operations.
Here's an example showing that effect:
using System;
class Test
{
static void Main()
{
double d1 = 0d;
for (int i = 0; i < 10000; i++)
{
d1 += 0.00000000000000001;
}
d1 += 1;
Console.WriteLine(d1);
double d2 = 1d;
for (int i = 0; i < 10000; i++)
{
d2 += 0.00000000000000001;
}
Console.WriteLine(d2);
}
}
In the first case, we can add very small numbers lots of times until they become big enough to still be relevant when added to 1.
In the second case, adding 0.00000000000000001 to 1 always just results in 1 as there isn't enough information in a double to represent 1.00000000000000001 - so the final result is still just 1.
EDIT: I've thought of another aspect which could be confusing things. For local variables, the JIT compiler is able to (and allowed to) use the 80-bit FP registers, which means arithmetic can be performed with less information loss. That's not the case for instance variables which definitely have to be 64-bit. In your Parallel.For case, the total variable will actually be an instance variable in a generated class because it's captured by a lambda expression. This could change the results - but it may well depend on computer architecture, CLR version etc.
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