Reputation: 7435
For example:
for(int i = 0; i < 20 * 40 * 60 * 80; i++){ ... }
Compared to:
for(int i = 0; i < 3840000; i++){ ... }
The first loop runs much slower than the second (did some time-trials) even though the value of the conditional will never change at any stage throughout the iteration. Sure, with methods this would be different because that value may change (even though it probably shouldn't). I was just wondering why Java doesn't cache / temp that value.
long fact10 = factorial(10);
for(long n = 0; n < fact10; n++) vs for(long n = 0; n < factorial(10); n++)
Upvotes: 4
Views: 130
Reputation: 635
What you have inside the loops since I wrote a small program and the time taken is almost same in both the cases. So it's really depends what you have inside first and second loop.
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int x = 0;
for (int i = 0; i < 500000000 ; i++) {
x++;
}
long endTime = System.currentTimeMillis();
long totalTime1 = endTime - startTime;
System.out.println("First time " + totalTime1);
startTime = System.currentTimeMillis();
int j = 0;
for (int i = 0; i < 50 * 100 * 10 * 10000 ; i++) {
j++;
}
endTime = System.currentTimeMillis();
long totalTime2 = endTime - startTime;
System.out.println("Second time " + totalTime2);
System.out.println( "First Loop " + totalTime1 + " Second Loop " + totalTime2 );
}
Upvotes: 0
Reputation: 1552
I think its okay, that the condition will checked each time. So you can implement something like this:
synchronized (veryBigList) {
for (Iterator iter = veryBigList.iterator();iter.hasNext();) {
Object o = iter.next();
//Do something
}
}
Notice, that some List Implementations have a different performance. I think (not sure now),
ArrayList is very fast on size()
, but slow on add()
if the
underlaying array have to be extended. LinkedList is slow on size()
,
but very fast on add()
I prefer this solution:
synchronized (veryBigList) {
for (int i = 0, l = veryBigList.size(); i < l; i++) {
//Do something
}
}
Upvotes: 0
Reputation:
I think your micro-benchmark is flawed, most are.
Benchmarking correctly is an art form. The Oracle JVM has a Just In Time compiler ( JIT ), I am sure if you ran this long enough you would see it eventually speed up after it decided heuristically that those values never change.
Upvotes: 2
Reputation: 727067
Java cannot do the second optimization, because it does not know that factorial
is free of side effects. As far as the first benchmark goes, I am sure this is a mistake of some sort: Java compiler calculates the results of constant expressions at compile time, so the first two loops are equivalent.
Upvotes: 6
Reputation: 6522
Theoretically (although I've had bad success with this), you could alter the result of your "<" statement in the loop.
For example:
int x = 1;
for(int i = 0; i < x * 2; i++)
{
if(x < 10)
x += i;
}
I don't know the exact reason why it does the calculation every time regardless of the values, but it always recalculates the mathematics during each iteration in case variables are present.
Upvotes: 0