Reputation:
So,
I've got a class called IntRectangle that holds int x1, int x2, int y1, int y2.
This is my assumption:
If I make the attributes above public I will get a performance boost, since I don't have to push and pop things when accessing them. I'll give it a shot.
public class CrapMain {
public void start () {
IntRectangle rec = new IntRectangle (5, 10, 6, 12);
int value = 0;
double time = System.nanoTime();
for (int i = 0; i < 1000000000; i++){
value = rec.X1;
}
time = System.nanoTime() - time;
System.out.println(time);
}
public static void main(String[] args) {
new CrapMain().start();
}
}
It prints 2559391.0
If I make the attributes private, create getters for them and change "value = rec.X1;" to "value = rec.getX1();" it prints 3551075.0
So there's obviously a performance boost given.
However, It makes the code venerable, since it's easy to change the attributes by mistake.
My question is, is it worth it? And is it common practice among programmers writing high-performance code?
Upvotes: 0
Views: 95
Reputation: 7267
No, it's almost never worth it.
Design your code sensibly using the best principles of OO design. If performance becomes an issue then it (probably) won't be due to object access, it'll be down to external resources or poor design, optimise at that point.
If your requirements mean that you're genuinely worried about the performance down to the nano second of a single statement, then write your program in assembler, there will be fewer factors to contend with.
Upvotes: 1
Reputation: 11925
Are you sure that this benchmark measures what you think it does? Microbenchmarks can become incredibly hard to get right.
Your benchmark measures the code before hotspot has kicked in and optimised the code. Infact the odds are you have benchmarked the Java Interpreter and not the execution time after the JIT has compiled your code to native assembler.
Modern JVMs can optimise getter methods out, or inline them; however they only do it after the JVM has 'warmed up' enough to have collected enough statistics that it then uses to optimise 'hotspots' in your code. Typically a method has to be run over ten thousand times before it will be up for optimisation. Your method is invoked only once, and has a very large loop in it, but it does not exit the method. This means that the if the JVM wanted to optimise that for loop while it was running it would have to perform 'on stack replacement' (OSR), which can and does happen but not very often in real production code. When it does happen, OSR optimised code is different to non-OSR optimised code, it has different performance characteristics.
So, in summary it is not clear that there would be any performance benefit from your experiment as it stands.
For advice on how to improve your benchmark, see How do I write a correct micro-benchmark in Java?
That said, if there was a performance gain, would it be worthwhile? That depends on context, how many times will one be making that call and what are the performance requirements for that section of code and the project? For the vast majority of cases, code clarity wins hands down.
Upvotes: 0