3

Possible Duplicate:
for loop optimization

Let's say we want to loop over the characters of a string s. I'd say the following code is more or less the default.

for( int i = 0; i < s.length(); i++ ) {
    doSomethingWith( s.charAt( i ) );
}

Question #1: Why do I often see the following?

final int length = s.length();
for( int i = 0; i < length; i++ ) {
    doSomethingWith( s.charAt( i ) );
}

At first sight this seems reasonable since the inequality is evaluated on every iteration. I would however expect the VM to optimize this anyway, since strings are immutable. Any thoughts? And what if we iterate over a mutable structure (that's not referenced by any other thread)? And what if length() is not guaranteed to run in O(1)?

Question #2: Some people seem to think substituting ++i for i++ speeds up the code. Are they right? Again this is not what I'd expect, but I'm simply not sure.

We all know not to optimize prematurely. At the same time, if we can produce slightly faster code at hardly any expense, we'd be silly not to. Of course one could argue that both "optimizations" hurt readability, but in my opinion the damage is so small that it would be justified in certain circumstances.

I tried to measure any differences in performance, but it's hard to get conclusive results. Although this should settle it for any specific application, I'm aiming for insight and a general answer here.

(Although I wrote this with the HotSpot VM in mind it could be interesting also to consider other platforms, like mobile devices.)

Community
  • 1
  • 1
Rinke
  • 6,095
  • 4
  • 38
  • 55

2 Answers2

5

Question #1: Why do I often see the following?

The first example is a premature optimization. The reason people do it is that they often don't profile their code to see where the real bottlenecks are, and instead just try to guess.

And what if length() is not guaranteed to run in O(1)?

Then it would make more sense to make this optimization. If you know that calculating the length is an expensive operation and that the value won't change, then calculating it once and storing the result could potentially improve performance.

Question #2: Some people seem to think substituting ++i for i++ speeds up the code. Are they right? Again this is not what I'd expect, but I'm simply not sure.

They aren't right. Their argument is that i++ has to create a temporary copy of the variable whereas ++i does not. This is something that used to be true in C or C++ a very long time ago when compilers were not good at optimizing. It is not true for Java.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
3

At first sight this seems reasonable since the inequality is evaluated on every iteration. I would however expect the VM to optimize this anyway, since strings are immutable.

The compiler optimizes this. Doing it like i < s.length(); is fine.

Some people seem to think substituting ++i for i++ speeds up the code.

It doesn't, unless you're assigning something to the return value of ++i

Jon Lin
  • 142,182
  • 29
  • 220
  • 220