Simple loop optimization

M

mrTriffid

Hi,

I'm interested in finding out something that's been bugging me for a
while now; does it make sense to optimize the following (idealised)
for-loop
for (int i = 0; i < foo.getBar(); i++)
into something like
for (int i = foo.getBar()-1; i >= 0; i--)
(assuming foo.getBar() doesn't change for the duration of the loop)?

In the first case, foo.getBar() is (theoretically) evaluated many
times, but only once in the second.

Ignoring the fact that the Java spec probably says nothing about such
optimizations, does it make sense to assume that (say) the vanilla Sun
JDK compiler would spot this, and would optimize the first loop to be
as good as the second?

Thanks in advance!
 
T

Tony Morris

mrTriffid said:
Hi,

I'm interested in finding out something that's been bugging me for a
while now; does it make sense to optimize the following (idealised)
for-loop
for (int i = 0; i < foo.getBar(); i++)
into something like
for (int i = foo.getBar()-1; i >= 0; i--)
(assuming foo.getBar() doesn't change for the duration of the loop)?

In the first case, foo.getBar() is (theoretically) evaluated many
times, but only once in the second.

Ignoring the fact that the Java spec probably says nothing about such
optimizations, does it make sense to assume that (say) the vanilla Sun
JDK compiler would spot this, and would optimize the first loop to be
as good as the second?

Thanks in advance!

This issue came up in the news thread titled "initialise byte array to
zero".
The eventual conclusion, after running some benchmarks (which I wouldn't say
were extensive, since it was not related to what was actually being
benchmarked), was that performance is not affected at all.

--
Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
(2003 VTR1000F)
 
C

Chris

mrTriffid said:
Hi,

I'm interested in finding out something that's been bugging me for a
while now; does it make sense to optimize the following (idealised)
for-loop
for (int i = 0; i < foo.getBar(); i++)
into something like
for (int i = foo.getBar()-1; i >= 0; i--)
(assuming foo.getBar() doesn't change for the duration of the loop)?

In the first case, foo.getBar() is (theoretically) evaluated many
times, but only once in the second.

Ignoring the fact that the Java spec probably says nothing about such
optimizations, does it make sense to assume that (say) the vanilla Sun
JDK compiler would spot this, and would optimize the first loop to be
as good as the second?

For most purposes, the difference in speed is not significant. I'd only
optimize if absolutely necessary.

That having been said, I often do something like this:

final int count = foo.getBar();
for (int i = 0; i < count; i++) {
}

The "final" gives the compiler a clue that count isn't going to change. It
also provides a little security against the possibility that the getBar()
value actually *does* change unexpectedly.

I would *not* make your code harder to read (by counting backwards) just to
squeeze out a few cycles.
 
E

Eric Sosman

mrTriffid said:
Hi,

I'm interested in finding out something that's been bugging me for a
while now; does it make sense to optimize the following (idealised)
for-loop
for (int i = 0; i < foo.getBar(); i++)
into something like
for (int i = foo.getBar()-1; i >= 0; i--)
(assuming foo.getBar() doesn't change for the duration of the loop)?

In the first case, foo.getBar() is (theoretically) evaluated many
times, but only once in the second.

.... so it's worth while if foo.getBar() is expensive and
returns a large value. If it's cheap or if its value is
small, it's not worth while. And above all, keep in mind
Jackson's Laws of Program Optimization:

First Law of Program Optimization:
Don't do it.

Second Law of Program Optimization (for experts only):
Don't do it yet.
 
H

Harald Kirsch

For most purposes, the difference in speed is not significant. I'd only
optimize if absolutely necessary.

That having been said, I often do something like this:

final int count = foo.getBar();
for (int i = 0; i < count; i++) {
}

In fact I prefer this last solution for better readability. By
assigning to 'count' before the loop I make explicit that I am *not*
doing any tricks with a variable upper bound of the loop.

Harald.
 
M

mrTriffid

Chris said:
For most purposes, the difference in speed is not significant. I'd only
optimize if absolutely necessary.

That having been said, I often do something like this:

final int count = foo.getBar();
for (int i = 0; i < count; i++) {
}

The "final" gives the compiler a clue that count isn't going to change. It
also provides a little security against the possibility that the getBar()
value actually *does* change unexpectedly.

My understanding is that final only affects the pointer^h^h^h^h^h^h^h
reference (*) value itself, and not what it points to though; so does
this actually help?

(*) Of course, I forgot, Java doesn't have pointers ;-)
 
C

Carl Howells

mrTriffid said:
My understanding is that final only affects the pointer^h^h^h^h^h^h^h
reference (*) value itself, and not what it points to though; so does
this actually help?

For reference types, your objection would be valid. But notice that
he's using a primitive type. A final primitive won't change, at all,
because it isn't a reference type.
 
R

Russ Tennant

Chris said:
For most purposes, the difference in speed is not significant. I'd only
optimize if absolutely necessary.

That having been said, I often do something like this:

final int count = foo.getBar();
for (int i = 0; i < count; i++) {
}

How about:

for (int i = 0, bound = foo.getBar(); i < bound; i++) {
}

This way the variable isn't too widely scoped if not needed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top