Direct access 300 times faster in Java?

Dear DZone and Reddit readers: Some test might result in a great difference between direct access and getters. Running a modified test with -server is 20 times faster for direct access compared to getters. If more stupid benchmarking is involved, this can increase. I suspect the server JVM is optimizing a lot. If you want to learn something, read the linked microbenchmark article 🙂 The difference between 300 and 20 is 15 times tough. A modified version which uses more than one test object seems to behave different (more than 2). See comments for a discussion on the causes - the JVM might completly inline an object if it detects only one read-access object inside a loop.

They sure seem to come in droves. After my last post, about a Ruby developer who is stupider than a piece of wood, there is another one! He laments how awful Java and OO developement is and how wonderful functional programming. Well functional development is nice, and I often use it with Java, but his post is rather funny because of the errors in it. The post is full of half-knowledge, things he quotes without any knowledge by himself. The blogosphere is full of those people.

I'm not refuting the article line by line, only the best parts:

"While we're harping about performance, consider that setter and getter methods [in Java] take 300 times longer than direct access. Not percent. Times."

I found this line hilarious.

public class Test {
  public int value = 42;
  public int getValue() {
    return value;
  }

  public static void main(String[] args) {
    Test test = new Test();
    int dummy;
    for (int i=0; i<1000000; i++) {
      dummy = test.value;
      dummy = test.getValue();
    }

    long tDirektStart = System.currentTimeMillis();
    long sum = 0L;
    for (int i=0; i<1000000000; i++) {
      sum += test.value;
    }
    long tDirekt = System.currentTimeMillis() - tDirektStart;

    sum= 0L;
    long tGetterStart = System.currentTimeMillis();
    for (int i=0; i<1000000000; i++) {
      sum += test.getValue();
    }
    long tGetter = System.currentTimeMillis() - tGetterStart;

    System.out.println("Direkt: " + tDirekt + " " + sum);
    System.out.println("Getter: " + tGetter + " " + sum);
  }
}

I know, micro benchmarking, I'm not sure what the JVM does in this case, inlining, loop unrolling, object removal, virtual methods and all - and it shouldn't matter because the JVM optimizing getters is the whole point, but it should enable us to look at the 300 times slower claim:


Direkt: 3470 42000000000
Getter: 3454 42000000000

300 times faster? You bet.

Oh, only one more:

So here's another problem, one that'll knock that smug look off the Pythonistas faces. If you've ever done a serious project in an OO language then you'll almost certainly have run into the fragile base class problem.

After more than 10 years of Java and lots of experience in C++, most people agree that inheritance should have been left out of every language - it might be good for frameworks but otherwise it does a lot of harm. The coupling is to big with inheritance. So for the last years people use more often composition not inheritance with Composite Oriented Programming being the extreme. Half knowledge and a blog - a dangerous combination. These "Get the facts" posts take to much time, I'll need to think about another format for them - or perhaps don't do any more of them.

The essence of it? Use the right tool, but don't get fooled by people with outrageous claims - most of the time they are wrong.

Thanks for listening.