Creating Variables in Advance to Use in Loops (?) - java

Which one of these two is more 'efficient':
for (int i = 0; i < 10; i++) {
int x = i * 2;
}
or -
int x;
for (int i = 0; i < 10; i++) {
x = i * 2;
}
(Just an example)
I understand they are different in essence - so please do not address the difference in their use.
In a case where both would prove to do the same thing - will creating the x variable multiple times be a less efficient method rather than just creating it once and simply reassigning its value?

No, in this case, with the way compilers are, there is no performance difference.
I prefer the first approach from a readability point of view, but that's something to be discussed elsewhere.
However, as a bonus section to this answer:
for (int x = 0; x < calculateUserCountFromDatabaseOrSomething(); x++) {
//Do stuff
}
In the above case, this will be a performance issue since the calculateUserCountFromDatabaseOrSomething() method is going to be called on every iteration of the loop. This is something that definitely needs to be considered when writing software.

The efficiency should be the same - I'd expect the byte code to be exactly the same.
However, what you should really care about is the readability and maintainability of the code, which is better in the first approach, as it limits the scope of x more - making it clearer where it will be used.
You should almost always care about readability over performance until you have evidence that not only is the less-readable alternative faster, but that the most readable solution is not fast enough.

If you want a definitive answer check this:
http://livingtao.blogspot.com/2007/05/myth-defining-loop-variables-inside.html
This conducts a byte code comparison of the results of compilation.
The answer is no difference by the way.

Depends on the type of the objects. For example if X is String it will make little difference. If for example X is some sort of Map, you can initialize it once, and clear it every time in the end of iteration. In the case X is int, it really does not matter, in terms of efficiency. Mind the scope of the variable, declaring it outside the loop suggests an intention, that it will be used after that.

Since you're allocating space for only one int instead of ten ints, in the second scenario, it should be faster. However, in reality the java compiler will almost certainly optimize this heavily to the point where microbenchmarks would say they took the same time.

The variable is not created multiple times:
for ( A; B; C ) {
D;
}
the execution is this:
A - (B - D - C) ... (B - D - C) until B became false

No performance benefits, both are same, but ,its better practice to declare your variables in as narrow a scope as possible, so as to make it more readable and clear.
Variables should only exist within the scope that they are used

Related

Big O complexity of nested loop depending on changing fraction result

Being relatively new to Big-Oh Notation and complexity analysis, I have been asked to determine the Big-Oh (tightest upper bound) time complexity of the following code.
Now as far as I can tell, for every iteration after the very first one (for which it would only run exactly once) the inner loop runs x2 meaning x times.
In itself this would be O(x).
y is never changed throughout the entire execution of the algorithm. However, n is incremented in every iteration, which affects the exit condition of the outer loop.
Because of the constant incrementation of n, the fraction serving as the exit condition of the outer loop becomes smaller and smaller.
Now if there was something like y/=2, and not y/n, every single time, I would immediately go for O(log y) runtime of the outer loop, but because of the changing denominator I'm thinking that we could view this as a factor, which --according to what I know about Big-Oh-- can be ignored, hence O(y) complexity of the outer loop, meaning O(x*y) complexity of the whole method.
Could anybody provide me with some guidance or a few tips regarding this? Any help would be greatly appreciated.
Thanks a lot!
void a (long x, long y){
long n = 0, x2 = n;
do {
do {
x2--;
} while (x2 > 0);
n++;
x2 = x;
} while (n < y / n);
}
EDIT: Thanks everybody for helping me out. Just as a little follow-up question: What would be the big-o complexity if the code were instead written like this:
void a(int x, int y) {
int n = 1;
do {
x++;
n++;
} while(y/n > x);
}
I tried rearranging it a little (e.g. y > n*x) and thinking of n as a constant that could be dropped which led me to believe that this would be O(y), but I feel like there is something I just don't yet understand about how these fractional conditions can be expressed in big O notation.
Could anybody provide me with some guidance or a few tips regarding this?
When in doubt count the operations performed.
For the purposes of complexity analysis1, it is a safe assumption that any primitive operation (arithmetic, test, branch) takes a constant amount of time. For these purposes, you can further assume that all primitive operations take the same time. So just add them all up.
Then work out an algebraic formula for the number of operations performed as a function of your variables; e.g. your x and y.
The other thing is that in order to figure out the complexity you will need to understand how the code works. Which can be a bit tricky when you have a mystery function like this one.
But even this one can be understood with some analytical thinking. For example, you can work out how many times x2 is going to be decremented in the inner loop ... by looking at the places where x2 is assigned to.
1 - This only applies to complexity analysis. If you are trying to estimate performance, these assumptions are not correct. Different operations take different times, and in some cases the time taken for a given operation could vary depending on the context; e.g. whether or not you get a cache hit. This is part of the reason that even roughly accurate a priori estimates of performance are really hard work.
Assuming the function is actually executed as written, the outer loop runs proportionally to sqrt(y) times, so the complexity of the entire function is O(x * sqrt(y)).
(It's worth noting that in real life, since the function has no side-effects, an optimizing compiler would probably replace it with a function that does nothing.)

Which is better to swap numbers? Using temporary variable or without it? Does it even matter?

I have been asked a question to swap two numbers without using temporary variable. It was a easy to answer the question with the following answer.
swapping with temp variable
int a =10;
int b =20;
int temp = a;
a = b;
b = temp;
swapping without temp variable
int a =10;
int b =20;
a = a+b;
b = a-b;
a = a-b;
It works, But which is better in terms of performance? When it is only one time operation performance doesn't matter i think. But if i need to reverse a huge array of numbers using this swapping method or during a selection sort where swapping needed etc.., creating local variable is better or doing it with arithmetic operation?
I will say definitely with a temp variable i.e. your first option. If you refer to your second example you have done total three operation. For each operation your java virtual machine generate equivalent assembly operation. But in your first option with a temp variable you are just swapping the values. Hence very minimal assembly operation only to read from address and write into address.
Quite apart from the fact that the second one can overflow*, there are three possible answers for this:
You can measure it.
Only think about this level of optimisation if you've measured it and this is really proven to be a problem. (In this instance it is highly unlikely that you'll be able to measure any appreciable difference.)
When in doubt, it's usually a good idea to choose the simpler / more canonical solution. A lot of optimisations are based on the premise that you write "normal" code, and will look for patterns developers usually employ. Naive optimisation efforts can sometimes result in inferior performance with Java Hotspot.
So unless you want to dive into the wonderful and tricky (but fun) world of microbenchmarking, just go with the temp variable.
*Though because of the way Java handles overflows, you'll still get the correct result. But as an aside, if you use xor instead of arithmetic operations, there is no danger of overflow.
P.s.: If you are reversing a huge array, the running time will be overwhelmingly dominated by memory access to the array.

Checking condition in loop [duplicate]

This question already has answers here:
Using collection size in for loop comparison
(4 answers)
for loop optimization
(15 answers)
Closed 9 years ago.
I would like to ask more experienced developers about one simple, but for me not obvious, thing. Assume you have got such a code (Java):
for(int i=0; i<vector.size(); i++){
//make some stuff here
}
I came across such statements very often, so maybe there is nothing wrong in it. But for me, it seems unnecessary to invoke a size method in each iteration. I would use such approach:
int vectorSize = vector.size();
for(int i=0; i<vectorSize; i++){
//make some stuff here
}
The same thing here:
for(int i=0; i<myTreeNode.getChildren().size(); i++){
//make some stuff here
}
I am definitely not an expert in programming yet, so my question is: Am I seeking a gap where the hedge is whole or it is important to take care of such details in professional code?
A method invocation requires that the JVM does indeed do additional stuff. So what you're doing, at first view seems like an optimization.
However, some JVM implementations are smart enough to inline method calls, and for those, the difference will be nonexistent.
The Android programming guidelines for example always recommend doing what you've pointed out, but again, the JVM implementation manual (if you can get your hands on one) will tell you if it optimizes code for you or not.
Usually size() is a small constant-time operation and so the cost of calling size is trivial compared to the cost of executing the loop body, and the just in time compiler may be taking care of this optimization for you; therefore, there may not be much benefit to this optimization.
That said, this optimization does not adversely affect code readability, so it isn't something to be avoided; often code optimizations that only affect speed by a small factor (as opposed to e.g. an optimization that changes a O(n) operation to a O(1) operation) should be avoided for this reason, for example you can unroll a loop:
int i;
int vectorSizeDivisibleBy4 = vectorSize - vectorSize % 4; // returns lowest multiple of four in vectorSize
for(i = 0; i < vectorSizeDivisibleBy4; i += 4) {
// loop body executed on [i]
// second copy of loop body executed on [i+1]
// third copy of loop body executed on [i+2]
// fourth copy of loop body executed on [i+3]
}
for(; i < vectorSize; i++) { // in case vectorSize wasn't a factor of four
// loop body
}
By unrolling the loop four times you reduce the number of times that i < vectorSize is evaluated by a factor of four, at the cost of making your code an unreadable mess (it might also muck up the instruction cache, resulting in a negative performance impact). Don't do this. But, like I said, int vectorSize = vector.size() doesn't fall into this category, so have at it.
At the 1st sight the alternative you are suggesting seams an optimization, but in terms of speed it is identical to the common approach, because of:
the complexity time of the call of size() function in a java vector has a complexity of order O(1) since each vector has always stored a variable containing its size, so you don't need to calculate its size in each iteration, you just access it.
note:
you can see that the size() function in: http://www.docjar.com/html/api/java/util/Vector.java.html is just returning a protected variable elementCount.

Technical reasons behind formatting when incrementing by 1 in a 'for' loop?

All over the web, code samples have for loops which look like this:
for(int i = 0; i < 5; i++)
while I used the following format:
for(int i = 0; i != 5; ++i)
I do this because I believe it to be more efficient, but does this really matter in most cases?
Everybody loves their micro-optimizations, but this would not make a difference as far as I can see. I compiled the two variations with g++ on for Intel processors without any fancy optimizations and the results are for
for(int i = 0; i < 5; i++)
movl $0, -12(%ebp)
jmp L2
L3:
leal -12(%ebp), %eax
incl (%eax)
L2:
cmpl $4, -12(%ebp)
jle L3
for(int i = 0; i != 5; ++i)
movl $0, -12(%ebp)
jmp L7
L8:
leal -12(%ebp), %eax
incl (%eax)
L7:
cmpl $5, -12(%ebp)
jne L8
I think jle and jne should translate to equally fast instructions on most architectures.
So for performance, you should not distinguish between the two. In general, I would agree that the first one is a little safer and I also think more common.
EDIT (2 years later): Since this thread recently got again a lot of attention, I would like to add that it will be difficult to answer this question generally. Which versions of code are more efficient is specifically not defined by the C-Standard [PDF] (and the same applies to C++ and probably also for C# ).
Section 5.1.2.3 Program execution
§1 The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
But it is reasonable to assume that a modern compiler will produce equally efficient code and I think that in only very rare cases will the loop-test and the counting expression be the bottleneck of a for-loop.
As for taste, I write
for(int i = 0; i < 5; ++i)
If for some reason i jumps to 50 in the loop, your version would loop forever. The i < 5 is a sanity check.
The form
for (int i = 0; i < 5; i++)
is idiomatic, so it's easier to read for experienced C programmers.
Especially when used to iterate over an array.
You should write idiomatic code whenever possible as it reads faster.
It is also a little safer in situations when you modify i inside the loop or use an increment different then 1.
But it's a minor thing.
It's best to carefully design your loop and add some asserts to catch broken assumptions early.
If the increment rule changes slightly you immediately have an infinite loop. I much prefer the first end condition.
It depends on the language.
C++ texts often suggest the second format as that will work with iterators which can be compared (!=) directly but not with a greater to or less than condition. Also pre increment can be faster than post increment as there is no need for a copy of the variable for comparison - however optimisers can deal with this.
For integers either form works. The common idiom for C is the first one whilst for C++ it is the second.
For C# and Java use I would foreach to loop over all things.
In C++ there is also the std::for_each function requiring a use of a functor which for simple cases is probably more complex than either example here and the Boost FOR_EACH which can look like the C# foreach but is complex inside.
With regards to using ++i instead of i++, it doesn't make a difference with most compilers, however ++i could be more efficient than i++ when used as an iterator.
There's actually four permutations on what you give. To your two:
for(int i = 0; i < 5; i++)
for(int i = 0; i != 5; ++i)
We can add:
for(int i = 0; i < 5; ++i)
for(int i = 0; i != 5; i++)
On most modern machines with modern compilers it shouldn't be surprising that these will be of exactly the same efficiency. It could be just about possible that you may one day find yourself programming for some small processor where there's a difference between equality comparisons and less-than comparisons.
It may in some case make more sense to a particular mind with a particular case to think of "less than" or of "not equals" depending on the reason why we chose 0 and 5, but even then what makes one seem obvious to one coder may not with another.
More abstractly, these are of the forms:
for(someType i = start; i < end; i++)
for(someType i = start; i != end; ++i)
for(someType i = start; i < end; ++i)
for(someType i = start; i != end; i++)
An obvious difference here is that in two cases someType must have a meaning for < and for the rest it must have a meaning for !=. Types for which != is defined and < isn't are quite common, including quite a few iterator objects in C++ (and potentially in C# where the same approach as STL iterators is possible and sometimes useful, but neither as idiomatic, directly supported by common libraries nor as often useful since there are rival idioms with more direct support). It's worth noting that the STL approach is specifically designed so as to include pointers within the set of valid iterator types. If you're in the habit of using the STL you'll consider the forms with != far more idiomatic even when applied to integers. Personally a very tiny amount of exposure to it was enough to make it my instinct.
On the other hand, while defining < and not != would be rarer, it's applicable to cases where either we replace the increment with a different increase in i's value, or where i may be altered within the loop.
So, there's definite cases on both sides where one or the other is the only approach.
Now for ++i vs i++. Again with integers and when called directly rather than through a function that returns the result (and chances are even then) the practical result will be exactly the same.
In some C-style languages (those without operator over-loading) integers and pointers are about the only cases there is. We could just about artificially invent a case where the increment is called through a function just to change how it goes, and chances are the compiler will still turn them into the same thing anyway.
C++ and C# allow us to override them. Generally the prefix ++ operates like a function that does:
val = OneMoreThan(val);//whatever OneMoreThan means in the context.
//note that we assigned something back to val here.
return val;
And the postfix ++ operates like a function that does:
SomeType copy = Clone(val);
val = OneMoreThan(val);
return copy;
Neither C++ nor C# match the above perfectly (I quite deliberately made my pseudo-code match neither), but in either case there may be a copy or perhaps two made. This may or may not be expensive. It may or may not be avoidable (in C++ we often can avoid it entirely for the prefix form by returning this and in the postfix by returning void). It may or may not be optimised away to nothing, but it remains that it could be more efficient to do ++i than i++ in certain cases.
More particularly, there's the slight possibility of a slight performance improvement with ++i, and with a large class it could even be considerable, but barring someone overriding in C++ so that the two had completely different meanings (a pretty bad idea) it's not generally possible for this to be the other way around. As such, getting into the habit of favouring prefix over postfix means you might gain an improvement mayone one time in a thousand, but won't lose out, so it's a habit C++ coders often get into.
In summary, there's absolutely no difference in the two cases given in your question, but there can be in variants of the same.
I switched to using != some 20+ years ago after reading Dijkstra's book called "A Discipline of Programming". In his book Dijkstra observed that weaker continuation conditions lead to stronger post-conditions in loop constructs.
For example, if we modify your construct to expose i after the loop, the post-condition of the fist loop would be i >= 5, while the post-condition of the second loop is a much stronger i == 5. This is better for reasoning about the program in formal terms of loop invariants, post-conditions, and weakest pre-conditions.
I agree with what's been said about readability - it's important to have code that's easy for a maintainer to read, although you'd hope that whoever that is would understand both pre- and post-increments.
That said, I thought that I'd run a simple test, and get some solid data about which of the four loops runs fastest.
I'm on an average spec computer, compiling with javac 1.7.0.
My program makes a for loop, iterating 2,000,000 time over nothing (so as not to swamp the interesting data with how long it takes to do whatever is in the for loop). It use all four types proposed above, and times the results, repeating 1000 times to get an average.
The actual code is:
public class EfficiencyTest
{
public static int iterations = 1000;
public static long postIncLessThan() {
long startTime = 0;
long endTime = 0;
startTime = System.nanoTime();
for (int i=0; i < 2000000; i++) {}
endTime = System.nanoTime();
return endTime - startTime;
}
public static long postIncNotEqual() {
long startTime = 0;
long endTime = 0;
startTime = System.nanoTime();
for (int i=0; i != 2000000; i++) {}
endTime = System.nanoTime();
return endTime - startTime;
}
public static long preIncLessThan() {
long startTime = 0;
long endTime = 0;
startTime = System.nanoTime();
for (int i=0; i < 2000000; ++i) {}
endTime = System.nanoTime();
return endTime - startTime;
}
public static long preIncNotEqual() {
long startTime = 0;
long endTime = 0;
startTime = System.nanoTime();
for (int i=0; i != 2000000; ++i) {}
endTime = System.nanoTime();
return endTime - startTime;
}
public static void analyseResults(long[] data) {
long max = 0;
long min = Long.MAX_VALUE;
long total = 0;
for (int i=0; i<iterations; i++) {
max = (max > data[i]) ? max : data[i];
min = (data[i] > min) ? min : data[i];
total += data[i];
}
long average = total/iterations;
System.out.print("max: " + (max) + "ns, min: " + (min) + "ns");
System.out.println("\tAverage: " + (average) + "ns");
}
public static void main(String[] args) {
long[] postIncLessThanResults = new long [iterations];
long[] postIncNotEqualResults = new long [iterations];
long[] preIncLessThanResults = new long [iterations];
long[] preIncNotEqualResults = new long [iterations];
for (int i=0; i<iterations; i++) {
postIncLessThanResults[i] = postIncLessThan();
postIncNotEqualResults[i] = postIncNotEqual();
preIncLessThanResults[i] = preIncLessThan();
preIncNotEqualResults[i] = preIncNotEqual();
}
System.out.println("Post increment, less than test");
analyseResults(postIncLessThanResults);
System.out.println("Post increment, inequality test");
analyseResults(postIncNotEqualResults);
System.out.println("Pre increment, less than test");
analyseResults(preIncLessThanResults);
System.out.println("Pre increment, inequality test");
analyseResults(preIncNotEqualResults);
}
}
Sorry if I've copied that in wrong!
The results supprised me - testing i < maxValue took about 1.39ms per loop, whether using pre- or post-increments, but i != maxValue took 1.05ms. That's a that's either a 24.5% saving or a 32.5% loss of time, depending on how you look at it.
Granted, how long it takes a for loop to run probably isn't your bottleneck, but this is the kind of optimisation that it's useful to know about, for the rare occasion when you need it.
I think I'll still stick to testing for less than, though!
Edit
I've tested decrementing i as well, and found that this doesn't really have an effect on th time it takes - for (int i = 2000000; i != 0; i--) and for (int i = 0; i != 2000000; i++) both take the same length of time, as do for (int i = 2000000; i > 0; i--) and for (int i = 0; i < 2000000; i++).
In generic code you should prefer the version with != operator since it only requires your i to be equally-comparable, while the < version requires it to be relationally-comparable. The latter is a stronger requirement than the former. You should generally prefer to avoid stronger requrements when a weaker requirement is perfectly sufficient.
Having said that, in your specific case if int i both will work equally well and there won't be any difference in performance.
I would never do this:
for(int i = 0; i != 5; ++i)
i != 5 leaves it open for the possibility that i will never be 5. It's too easy to skip over it and run into either an infinite loop or an array accessor error.
++i
Although a lot of people know that you can put ++ in front, there are a lot of people who don't. Code needs to be readable to people, and although it could be a micro optimization to make the code go faster, it really isn't worth the extra headache when someone has to modify the code and figure why it was done.
I think Douglas Crockford has the best suggestion and that is to not use ++ or -- at all. It can just become too confusing (may be not in a loop but definitely other places) at times and it is just as easy to write i = i + 1. He thinks it's just a bad habit to get out of, and I kind of agree after seeing some atrocious "optimized" code.
I think what crockford is getting at is with those operators you can get people writing things like:
var x = 0;
var y = x++;
y = ++x * (Math.pow(++y, 2) * 3) * ++x;
alert(x * y);
//the answer is 54 btw.
It is not a good idea to care about efficiency in those cases, because your compiler is usually smart enough to optimize your code when it is able to.
I have worked to a company that produces software for safety-critical systems, and one of the rules was that the loop should end with a "<" instead of a !=. There are several good reasons for that:
Your control variable might jump to a higher value by some hw problem or some memory invasion;
In the maintenance, one could increment your iterator value inside the loop, or do something like "i += 2", and this would make your loop to roll forever;
If for some reason your iterator type changes from "int" to "float" (I don't know why someone would do that, but anyways...) an exact comparison for float points is a bad practice.
(The MISRA C++ Coding Standard (for safety-critical systems) also tell you to prefer the "<" instead of "!=" in the rule 6-5-2. I don't know if I can post the rule definition here because MISRA is a paid document.)
About the ++i or i++, I'd preffer to use ++i. There is no difference for that when you are working with basic types, but when you are using a STL iterator, the preincrement is more efficient. So I always use preincrement to get used to it.
I have decided to list the most informative answers as this question is getting a little crowded.
DenverCoder8's bench marking clearly deserves some recognition as well as the compiled versions of the loops by Lucas. Tim Gee has shown the differences between pre & post increment while User377178 has highlighted some of the pros and cons of < and !=. Tenacious Techhunter has written about loop optimizations in general and is worth a mention.
There you have my top 5 answers.
DenverCoder8
Lucas
Tim Gee
User377178
Tenacious Techhunter
For the record the cobol equivalent of the "for" loop is:-
PERFORM VARYING VAR1
FROM +1 BY +1
UNTIL VAR1 > +100
* SOME VERBOSE COBOL STATEMENTS HERE
END-PERFORM.
or
PERFORM ANOTHER-PARAGRAPH
VARYING VAR2 BY +1
UNTIL TERMINATING-CONDITION
WITH TEST AFTER.
There are many variations on this. The major gotcha for peoples whose minds have not been damaged by long exposure to COBOL is the, by default, UNTIL actually means WHILE i.e. the test is performed at the top of the loop, before the loop variable is incremented and before the body of the loop is processed. You need the "WITH TEST AFTER" to make it a proper UNTIL.
The second is less readable, I think (if only because the "standard" practice seems to be the former).
Numeric literals sprinkled in your code? For shame...
Getting back on track, Donald Knuth once said
We should forget about small
efficiencies, say about 97% of the
time: premature optimization is the
root of all evil.
So, it really boils down to which is easier to parse
So... taking into account both of the above, which of the following is easier for a programmer to parse?
for (int i = 0; i < myArray.Length; ++i)
for (int i = 0; i != myArray.Length; ++i)
Edit: I'm aware that arrays in C# implement the System.Collections.IList interface, but that's not necessarily true in other languages.
Regarding readability. Being a C# programmer who likes Ruby, I recently wrote an extension method for int which allows the following syntax (as in Ruby):
4.Times(x => MyAction(x));
To sum up pros and cons of both options
Pros of !=
when int is replaced with some iterator or a type passed via template argument there is better chance it will work, it will do what is expected and it will be more efficient.
will 'loop forever' if something unpredicted happens to the i variable allowing bug detection
Pros of <
as other say is as efficient as the other one with simple types
it will not run 'forever' if i is increased in the loop or 5 is replaced with some expression that gets modified while the loop is running
will work with float type
more readable - matter of getting used to
My conclusions:
Perhaps the != version should be used in majority of cases, when i is discrete and it is as well as the other side of the comparison is not intended to be tampered within the loop.
While the presence of < would be a clear sign that the i is of simple type (or evaluates to simple type) and the condition is not straightforward: i or condition is additionally modified within the loop and/or parallel processing.
It appears no one has stated the reason why historically the preincrement operator, ++i, has been preferred over the postfix i++, for small loops.
Consider a typical implementation of the prefix (increment and fetch) and the postfix (fetch and increment):
// prefix form: increment and fetch
UPInt& UPInt::operator++()
{
*this += 1; // increment
return *this; // fetch
}
// posfix form: fetch and increment
const UPInt UPInt::operator++(int)
{
const UPInt oldValue = *this;
++(*this);
return oldValue;
}
Note that the prefix operation can be done in-place, where as the postfix requires another variable to keep track of the old value. If you are not sure why this is so, consider the following:
int a = 0;
int b = a++; // b = 0, the old value, a = 1
In a small loop, this extra allocation required by the postfix could theoretically make it slower and so the old school logic is the prefix is more efficient. As such, many C/C++ programmers have stuck with the habit of using the prefix form.
However, noted elsewhere is the fact that modern compilers are smart. They notice that when using the postfix form in a for loop, the return value of the postfix is not needed. As such, it's not necessary to keep track of the old value and it can be optimized out - leaving the same machine code you would get from using the prefix form.
Well... that's fine as long as you don't modify i inside your for loop. The real "BEST" syntax for this entirely depends on your desired result.
If your index were not an int, but instead (say) a C++ class, then it would be possible for the second example to be more efficient.
However, as written, your belief that the second form is more efficient is simply incorrect. Any decent compiler will have excellent codegen idioms for a simple for loop, and will produce high-quality code for either example. More to the point:
In a for loop that's doing heavy performance-critical computation, the index arithmetic will be a nearly negligible portion of the overall load.
If your for loop is performance-critical and not doing heavy computation such that the index arithmetic actually matters, you should almost certainly be restructuring your code to do more work in each pass of the loop.
When I first started programming in C, I used the ++i form in for loops simply because the C compiler I was using at the time did not do much optimization and would generate slightly more efficient code in that case.
Now I use the ++i form because it reads as "increment i", whereas i++ reads as "i is incremented" and any English teacher will tell you to avoid the passive voice.
The bottom line is do whatever seems more readable to you.
I think in the end it boils down to personal preference.
I like the idea of
for(int i = 0; i < 5; i++)
over
for(int i = 0; i != 5; ++i)
due to there being a chance of the value of i jumping past 5 for some reason. I know most times the chances on that happening are slim, but I think in the end its good practice.
We can use one more trick for this.
for (i = 5; i > 0; i--)
I suppose most of the compilers optimize the loops like this.
I am not sure. Someone please verify.
Ultimately, the deciding factor as to what is more efficient is neither the language nor the compiler, but rather, the underlying hardware. If you’re writing code for an embedded microcontroller like an 8051, counting up vs. counting down, greater or less than vs. not equals, and incrementing vs. decrementing, can make a difference to performance, within the very limited time scale of your loops.
While sufficient language and compiler support can (and often do) mitigate the absence of the instructions required to implement the specified code in an optimal but conceptually equivalent way, coding for the hardware itself guarantees performance, rather than merely hoping adequate optimizations exist at compile time.
And all this means, there is no one universal answer to your question, since there are so many different low-end microcontrollers out there.
Of much greater importance, however, than optimizing how your for loop iterates, loops, and breaks, is modifying what it does on each iteration. If causing the for loop one extra instruction saves two or more instructions within each iteration, do it! You will get a net gain of one or more cycles! For truly optimal code, you have to weigh the consequences of fully optimizing how the for loop iterates over what happens on each iteration.
All that being said, a good rule of thumb is, if you would find it a challenge to memorize all the assembly instructions for your particular target hardware, the optimal assembly instructions for all variations of a “for” loop have probably been fully accounted for. You can always check if you REALLY care.
I see plenty of answers using the specific code that was posted, and integer. However the question was specific to 'for loops', not the specific one mentioned in the original post.
I prefer to use the prefix increment/decrement operator because it is pretty much guaranteed to be as fast as the postfix operator, but has the possibility to be faster when used with non-primitive types. For types like integers it will never matter with any modern compiler, but if you get in the habit of using the prefix operator, then in the cases where it will provide a speed boost, you'll benefit from it.
I recently ran a static analysis tool on a large project (probably around 1-2 million lines of code), and it found around 80 cases where a postfix was being used in a case where a prefix would provide a speed benefit. In most of these cases the benefit was small because the size of the container or number of loops would usually be small, but in other cases it could potentially iterate over 500+ items.
Depending on the type of object being incremented/decremented, when a postfix occurs a copy can also occur. I would be curious to find out how many compilers will spot the case when a postfix is being used when its value isn't referenced, and thus the copy could not be used. Would it generate code in that case for a prefix instead? Even the static analysis tool mentioned that some of those 80 cases it had found might be optimized out anyway, but why take the chance and let the compiler decide? I don't find the prefix operator to be at all confusing when used alone, it only becomes a burden to read when it starts getting used, inline, as part of a logic statement:
int i = 5;
i = ++i * 3;
Having to think about operator precedence shouldn't be necessary with simple logic.
int i = 5;
i++;
i *= 3;
Sure the code above takes an extra line, but it reads more clearly. But with a for loop the variable being altered is its own statement, so you don't have to worry about whether it's prefix or postfix, just like in the code block above, the i++ is alone, so little thought is required as to what will happen with it, so this code block below is probably just as readable:
int i = 5;
++i;
i *= 3;
As I've said, it doesn't matter all that much, but using the prefix when the variable is not being used otherwise in the same statement is just a good habit in my opinion, because at some point you'll be using it on a non-primitive class and you might save yourself a copy operation.
Just my two cents.
On many architectures, it is far easier to check whether something is zero that whether it is some other arbitrary integer, therefore if you truly want to optimize the heck out of something, whenever possible count down, not up (here's an example on ARM chips).
In general, it really depends on how you think about numbers and counting. I'm doing lots of DSP and mathematics, so counting from 0 to N-1 is more natural to me, you may be different in this respect.
FORTRAN's DO loop and BASIC's FOR loop implemented < (actually <=) for positive increments. Not sure what COBOL did, but I suspect it was similar. So this approach was "natural" to the designers and users of "new" languages like C.
Additionally, < is more likely than != to terminate in erroneous situations, and is equally valid for integer and floating point values.
The first point above is the probable reason the style got started, the second is the main reason it continues.
I remember one code segment where the i was getting incremented by 2 instead of 1 due to some mistake and it was causing it to go in infinite loop. So it is better to have this loop as shown in the first option. This is more readable also. Because i != 5 and i < 5 conveys two different meaning to the reader. Also if you are increasing the loop variable then i<5 is suppose to end some point of time while i != 5 may never end because of some mistake.
It is not good approach to use as != 5. But
for (int i =0; i<index; ++i)
is more efficient than
for(int i=0; i<index; i++)
Because i++ first perform copy operation. For detailed information you can look operator overloading in C++.

What is more efficient, i++ or ++i? [duplicate]

This question already has answers here:
Closed 14 years ago.
Exact Duplicate: Is there a performance difference between i++ and ++i in C++?
Exact Duplicate: Difference between i++ and ++i in a loop?
What is more efficient, i++ or ++i?
I have only used this in Java and C/C++, but I am really asking for all languages that this is implemented in.
In college I had a professor show us that ++i was more efficient, but it has been a couple of years, and I would like to get input from the Stack Overflow community.
i++ :
create a temporary copy of i
increment i
return the temporary copy
++i :
increment i
return i
With optimizations on, it is quite possible that the resulting assembly is identical, however ++i is more efficient.
edit : keep in mind that in C++, i may be whatever object that support the prefix and postfix ++ operator. For complex objects, the temporary copy cost is non negligible.
I would look elsewhere for optimization potential.
Efficiency shouldn't be your concern: it is meaning. The two are not the same, unless they are freestanding: one operates pre-use of the value, the other post.
int i;
i = 1;
cout << i++; //Returns 1
int i;
i = 1;
cout << ++i; //Returns 2
When meaning isn't important, most compilers will translate both ++i and i++ (say in a for loop) into the same machine/VM code.
It does not matter on a modern compiler.
int v = i++;
is the same as
int v = i;
i = i + 1;
A modern compiler will discover that v is unused and the code to calculate v is pure (no side effects). Then it will remove v and the assignment code and will generate this
i = i + 1;
It does matter! Especially if you're in C++ land with custom iterator protocols...
++i // the prefered way, unless..
auto j = i++ // this is what you need
You should use the prefix notation to avoid a necessary copying overhead but it only applies to iterators, it doesn't apply to builtin native types, those are just one instruction regardless.
++i is potentially more efficient for a non-trivial implementation of operator++, but even in that scenario, the compiler may be able to optimize away the intermediate temporary.
++i doesn't need a temporary variable to store stuff in. Think of them like this:
++i
int preIncrement(int i)
{
i = i + 1;
return i;
}
i++
int i = 5; // as an example
int postIncrement(_i)
{
int temp = _i;
i = _i + 1;
return temp;
}
See? Postincrement requires a temporary variable. Assuming the compiler doesn't sort it all out for you, which it almost certainly does.
Of course, more important is program logic; you run the risk of encountering The Sad Tragedy of Micro-Optimisation Theatre if you worry about this too much...:)
Well, in C++ I believe they have different uses, depending on when you want the variable updated.
Efficiency shouldn't determine when you use one over the other, but I would assume they would have the same efficiency either way.
Unless I'm missing something, they should have the same efficiency. They should both result in a single add instruction. It's just a matter of where the add instruction takes place: at the beginning or the end of your line of code.
++i is faster because i++ has to store i, then increment it, then return the stored value of i. ++i simply increments i then returns it.
// ++i
i += 1;
return i;
// i++
temp = i;
i += 1;
return temp;
A stand-alone "i++;" or "++i;" should generate equally efficient code. The difference comes if you're using it in an expression, where the "side effect" comes into play.
That said, there was a time, back when "all the world's a Vax", and compilers sucked, that ++i was said to be more efficient that i++, even in a "for (i = 0; i < N; ++i)" type setting.
In general, it is more efficient to use ++i than i++.
The simple reason for this is that ++i is utterly the same as
i += 1;
which for x86 is a single instruction (and likely most other widely used architectures).
i++ is however equal to
tmp = i; i += 1;
That is because the old value of 'i' is what i++ evaluates to. And clearly that requires more work than simply i += 1;
But as stated above, this has virtually no impact with a sufficiently clever compiler, as it will optimize unused operations away. For many interpreted languages (example: PHP) there is likely a minimal gain in speed for the ++i; But this increase is negligible.
It's generally easier to type i++, hence it is more efficient in terms of productivity time.
Seriously, though, if i is a native data type (such as int, double, etc) -- no difference.
And it is implementation depended if it's a user-defined type such as
class Type
{
Type& operator ++(){}
const Type& operator ++(int i){}
};
T i;
++i takes one less processor instruction than i++ in x86 assembly without optimization.
There is no difference. Use the construct that makes the most sense.
If your application runs slowly, I can guarantee you that it will never be because of speed differences in the integer increment operation. If it is, it's a severe bug in the compiler. Speed
problems in your application will be algorithmic inefficiencies, waiting for I/O, and so on.
Don't worry about problems that you don't have. Premature optimization is the root of all evil.
This Stack Overflow question has a great answer: Is there a performance difference between i++ and ++i in C?
I would like to add that you should use whichever one suits your needs better. Except in the most time critical of applications, it is not important. From an academic perspective too, it is better to write code that expresses what you need and optimize at last.
There is no right or wrong answer.
As it depends on:
How it was implemented by the compiler.
What CPU the system runs on.
If i is byte or i is double word
It depends upon the context, for example:
x = i++
In this case, 'x' will be equal to 'i', and only after that will 'i' be increased by one.
x = ++i
In this case, 'i' will be increase by one and then the new value of 'x' will be assigned to 'x'.
In the case of a 'for' loop, there is little apparent difference other than performance (++i is faster).
Generally, in C++, postfix will require the additional construction of the object incremented, while prefix is applied directly to the object. (Or so I've read.)
As I am unable to attest to how the compiler handles it due to my limited knowledge on the matter, it could be handled for you making it a moot point.
It's hard to answer this precisely as it depends on the compiler/interpreter implementation.
But generally speaking you can say roughly extend i++ to the following instructions:
COPY i to tmp
INCREMENT tmp
SAVE tmp as i
While ++i will roughly extend to:
LOAD i
INCREMENT i
You can't just say that ++i is faster than i++ since language implementations are pretty smart and they can optimize these instructions when you know that you won't access the temporary value of i++. This usually happens in say a for loop. So in many cases it's just the same.
If you're trying to these kind of micro-optimizations I'd advice you to profile/measure before chosing one over another.

Categories