#

What’s faster: method call or public access?

Several times when I was writing java classes, I woundered, what would lead to a better performance: calls to a getter method returning some private attributes or declaring the attribute public and accessing it directly.

From the viewpoint of object oriented programming creating getters and setters to a private attribute is always better. It encapsulates better and you have the chance to monitor changes to attributes through the setters, for example to implement an observer pattern. On the other side, calling methods should lead to programmatic overhead, like heap reservation, parameter pasing etc. Classes like the java.awt.Point or java.awt.Dimension allow direct access to their public declared values. So I wanted to testify my assumptions and wrote a little benchmark:

public class X{
public double x;
 
public X(double xx){
x=xx;
}
}
 
public class Y{
private double x;
 
public Y(double xx){
x=xx;
}
 
public double getX(){
return x;
}
}
 
public class Test {
public static void main(String[] args) {
test(1000);
testStat(100000000, 10);
testStat(1000000000, 10);
testStat(10000000000L, 10);
}
 
public static void testStat(long amount, int statamount){
long [] sum = new long[2];
long [] single;
for (int i=0; i<statamount; i++){
single = test(amount);
sum[0]+=single[0];
sum[1]+=single[1];
}
sum[0] /= statamount;
sum[1] /= statamount;
System.out.println("Avg. results: "+sum[0]+" ms "+sum[1]+" ms");
}
 
public static long [] test(long amount){
long [] result = new long[2];
System.out.println();
System.out.println("Testing "+Long.toString(amount)+" times:");
long starttime, endtime;
X x = new X(100);
Y y = new Y(100);
double w;
 
starttime=System.currentTimeMillis();
for (long i=0; i<amount; i++)
w = x.x;
endtime=System.currentTimeMillis();
result[0] = endtime-starttime;
System.out.println(result[0]+" ms");
 
starttime=System.currentTimeMillis();
for (long i=0; i<amount; i++)
w = y.getX();
endtime=System.currentTimeMillis();
result[1] = endtime-starttime;
System.out.println(result[1]+" ms");
return result;
}
}

This benchmark lead to the following results:

  • avg. results for 10^9 cycles
    Class X: 4545 ms Class Y: 4609 ms
  • avg. results for 10^10 cycles
    Class X: 45454 ms Class Y: 45945 ms
  • Since this results are not 100% representative (I had several tasks in the background), I will verify them on other machines and constellations. (If you like, do so, too and post it here.)
    But at all it seems, that the performance difference between method invokations and direct public access is not that big. At least small enough to prefer the object oriented approach through getters.

    Tags:, ,

    2 Responses to “What’s faster: method call or public access?” »»

    1. Comment by Toni | 20:25 13.10.05|X

      I am sorry to say so, but you are making a very common mistake here. You do a microbenchmark and assume that it has some validity performancewise, when really in the background the jvm is doing something else. What I am talking about is the JIT capabilities of the JVM and not only JIT but also the compilier inlining feature. Let me show you something I found in an Article from 1998.

      Fortunately, today’s JIT-enabled Java environments perform method calls much faster than earlier non-JIT-enabled environments. There is less of a need to make speed-versus-encapsulation tradeoffs in these environments. With the best JIT, static methods returning nothing and taking no arguments execute in 2 clock cycles. Non-static method calls returning integer quantities execute in 7 clock cycles. Non-static method calls returning floating-point numbers execute in 8 clock cycles.

      Taken from a really old article on Javaworld

      This, and the compiler inlining makes this benchmark invalid. You may have measured something that in real life would perform otherwise. 2005’s JDK 1.5 is so complex and feature ridden, that microbenchmarking something like that is just not fair. Rest assured, you will not loose performance because of method calls – well, unless you really mess up the jvm 😉

    2. Comment by Secco | 10:21 18.10.05|X

      Well, you’re all right. I had read about the optimization called inlining and am aware, that the microbenchmark is not that representative in general. My aim was to decide which one of those approaches to use in a more complex architecture. Imagine I wanted to implement a directed bigraph. There are several approaches doing so, like using adjacence matrices or adjacence lists. both of this approaches need access to several values stored in a class: the matrix needs a 2 dimensional array while the adjacence lists need linked or hashed lists. So I had to decide weather it’s worth making all the arrays and lists public or encapsulate them through method calls since there would be thousands of thousands of calls to them. The experiment was just designed therefor and is so quite representative. If using getters, I just would return a value from an array or list. This experiments showed me, that, eg through the inline capability, the method encapsulation is more prefferable, since there is realy low speedloss but a very high gain of objectorientation, readability and reusability.

    Leave a Reply »»

    Note: All comments are manually approved to avoid spam. So if your comment doesn't appear immediately, that's ok. Have patience, it can take some days until I have the time to approve my comments.