5

I am asking this question purely for the speed aspects of the question.

What is the difference in speed between getting the value from an object when it is private or public (Java)?

class MyClass {
    public int myInt = 5;
}
class MyOtherClass {
    private int myInt = 5;

    public int getMyInt() {
        return myInt;
    }
}
class MyMainClass {
    public static void main (String [] args) {
        MyClass myObject = new MyClass();
        MyOtherClass myOtherObject = new MyOtherClass();

        // which is faster?
        System.out.println(myObject.myInt);
        System.out.println(myOtherObject.getMyInt ());
    }
}

I know I can test it, but if anyone alreay knows it, it can't hurt :) Thanks in advance!

Hidde
  • 11,493
  • 8
  • 43
  • 68
  • You *should* test it. And you shouldn't microbenchmark it but try it on a large program that actually does some useful work, and let it run for a minute, because that's the dimensions where optimizations matter at all. Do this every time you think about micro-optimizing until that waste of energy is removed from your thinking process. –  Sep 09 '11 at 17:43
  • @delnan, I'm not sure what you mean by this. If you mean that in the context of a large program, a `particular` optimization may have an immeasurable benefit, that is sort of true by definition. Wouldn't a specially coded test, still be informative in respect to a generally applicable understanding of which way is better? Of course you would probably want to iterate for a long time since you don't know when memory management functions run, etc. I don't see the need for a real world program that does real work. – H2ONaCl Nov 15 '11 at 03:32
  • @broiyan: If it only has any (relevant) effect for microbenchmarks, then programs that actually solve problems don't benefit from it. If it doesn't speed up solving real problems, it adds zero value and is not worth worrying about. Nobody cares if it makes your microbenchmark run faster. This goes thrice if there's a technical depth (e.g. worse design due to less encapsulation). The optimizations that are worth worrying about and implementing bring measureable benefits even in real-world programs that do tons of other things (remember the 80-20 rule!). –  Nov 15 '11 at 16:48

5 Answers5

13

Public and private access is nothing more than determining at compile time whether or not you have access to a variable. At run time, they are exactly the same. This means if you can trick the JVM into thinking you have access (through reflection, unsafe, or modifying the bytecode) then you can. Public and private is just compile time information. That's not to say it doesn't get stored in the bytecode, because it does, but only so it can be referenced if something tries to compile against it.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • And the hassle of calling a function does not matter at all? – Hidde Sep 09 '11 at 17:37
  • 1
    @Hidde: After the JIT kicks in, it's very easy for it to inline that call. And even if it doesn't, there are a million things you can optimize to much greater effect without changing your design for worse. –  Sep 09 '11 at 17:39
  • Actually in this case, probably not. It is probably in-lined by the compiler. For a non-trivial method, yes a method call will incur a small performance hit, but it's incredibly unlikely you'll have a method more than a couple lines for a getter method. – corsiKa Sep 09 '11 at 17:39
  • Thanks :) I actually totally forgot about inline functions. – Hidde Sep 09 '11 at 17:50
  • 1
    It will only get inlined by the compiler if it the method is `final`, and the inlined access would not violate access controls. Otherwise, it has to wait until runtime. – erickson Sep 09 '11 at 17:52
  • That's true, erickson. And that makes it especially slower if it only gets used once and has to get compiled to do so. However, – corsiKa Sep 09 '11 at 17:55
  • This answer is very wrong. The bytecode verifier - which works at runtime (class load time) - enforces access restrictions. If you modify the bytecode, the bytecode verifier will catch this. And reflection is restricted by the Java security model - which isn't enabled in many cases, but is still available. – Erwin Bolwidt Sep 29 '16 at 13:43
  • The bytecode verifier has no way of knowing whether or not you intended to have a field public or private - it just guarantees that all accesses follow the model presented. If I change the bytecode of a class to make its field public instead of private, the bytecode verifier will happily allow other classes to reference that field directly. The last clause of the last sentence might not be 1000% accurate, but it's pretty darned close. "Very wrong" is a mischaracterization of the answer. – corsiKa Sep 29 '16 at 17:51
  • @korsiKa "Public and private access is nothing more than determining at compile time whether or not you have access to a variable. At run time, they are exactly the same." that really gives the wrong impression to people. The byte code verifier - a runtime component - is responsible for enforcing access checks. It's not "nothing more than compile time" – Erwin Bolwidt Sep 30 '16 at 01:09
  • @ErwinBolwidt You need to read my answer in the context of the question. Specifically, the first line "I am asking this question purely for the speed aspects of the question." You are technically correct that there is a step between compile and end-user run time where there is an additional access check, but that has literally zero bearing on the speed of the operations. And for what it's worth, 99% of Java developers will never know the bytecode verifier even exists. So it only gives the wrong impression to the 1% of developers for which something like that actually matters. – corsiKa Sep 30 '16 at 01:18
9

The access modifier on the field doesn't make any difference in speed, but invoking the accessor method does.

However, the difference isn't great, and is likely to diminish after repeated invocations due to JIT compiler optimizations. It depends on your situation, but I haven't found a case where performance concerns justified the elimination of an accessor. Let good design principles drive your decisions.

One good design principle that will help performance in this case is to prohibit inheritance unless you know it is needed and have taken steps to support it. In particular, declaring the class to be final (or at least the accessor method) will provide faster method dispatch and might also serve as a hint to the JITC to inline more agressively.

Keeping accessors final also allows the compiler to inline calls to the accessor. If the field is private, calls to the accessor from within the class can be inlined (and in a good design, these are far and away the most common case), while a package accessible field can be inlined throughout the package, etc.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • Big +1 for a number of good pearls of wisdom. Design principles > performance (especially a microoptimization like this) is one of them. Making it final is also a fairly decent idea, since I would consider it unwise to have a straight-up accessor method overridden in a child class, giving me no reason not to make it final. – corsiKa Sep 09 '11 at 17:51
1

As far as I know, when you're calling a getter or any function that will just return some value and nothing else, this method will get inlined so there's no difference whatsoever between the method call and the dirrect access of the field.

asenovm
  • 6,397
  • 2
  • 41
  • 52
1

You ask about accessing private vs. public variables, but your code example and comment to glowcoder hint that you're really asking about private fields vs. public methods (or, fields vs. methods ... as glowcoder correctly said, public vs. private has no impact on performance).

Many modern compilers will optimize calls to short methods to be equivalent to access to the field they wrap (by inlining the call), but it's entirely possible that a given Java environment will perform a function call instead (which is slightly slower) to invoke the method.

It's up to the particular compiler whether to generate inline code or a function call. Lacking knowledge of which java compiler you're using (and possibly which compiler options), it's not possible to say for sure.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
0

From a performance perspective, the difference is infinitesimal, if there's any difference at all. The compiler is going to optimize this code almost identically, and once the code is compiled, the JVM is going to treat public and private variables exactly the same way (I don't believe it even knows about the distinction between public and private post-compilation).

From a pragmatic standpoint, it's difficult to conceive of any possible scenario where it's worth breaking the traditional Java attribute access pattern for performance purposes. There was a similar question asked on StackOverflow on this subject for C++, and the answers are just as relevant for Java:

Any performance reason to put attributes protected/private?

Community
  • 1
  • 1
Dan Koch
  • 1
  • 1
  • 1