2

I was reading this: http://developer.android.com/training/articles/perf-tips.html

Particularly this about internal getters and setters:

Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter.

It mentions "virtual method calls" which, probably, also refer to public methods. I have a bunch of methods in my class where the methods shouldn't be overridden. For example:

public class Something {
    private float m_Float = 0.0f;
    public float getFloat () {
        return m_Float;
    }
}

I always want 'getFloat()' to return 'm_Float', even in derived classes. Does marking the method 'final' improve performance for Android devices? Even if it doesn't, is final-correctness as important as const-correctness? Like, do Java programmers get anal when fellow colleagues forget about final-correctness?

If marking the method final improves performance, is the performance gain nullified for the following?

public class Base {
    public int getRandomNumber () {
        return 4; //chosen by fair dice roll.
                  //guaranteed to be random.
    }
}
public class Derived extends Base {
    public final int getRandomNumber () {
        return 6; //chosen by second fair dice roll.
                  //guaranteed to be more random.
    }
}

I'm not really interested in optimizing my code at this point but I am interested in the final-correctness bit.. I'm not familiar with the standard conventions where Java's concerned.

[EDIT]

Okay, so, above, this link is given as a possible answer: Android Performance - 'Avoid Internal Getters/Setters'

The reply marked as the answer links to this: What optimizations can I expect from Dalvik and the Android toolchain?

It seems that simple getters and setters are inlined now.

In Gingerbread we added simple inlining for getters/setters. Since the underlying JIT frontend is still simple trace based, if the callee has branches in there it won't be inlined. But the inline cache mechanism is implemented so that virtual getters/setters can be inlined without problems.

And in the comments, this is asked:

(3) Should I declare my methods final wherever possible? Or does that still count as a virtual callsite?

And this is the reply:

(3) Yes please

So, with the comments here and whatnot, I'd say everything's resolved. (Except for when final should be used with methods; but that will probably be answered very soon. I have a belief but am waiting for it to get validated or refuted with a reason, so..)

[EDIT]

Also, doesn't this mean that the Android docs. about performance tips is.. outdated?

Community
  • 1
  • 1
Justin AnyhowStep
  • 1,130
  • 3
  • 12
  • 19
  • 3
    Final in front of a method declaration just means you can't override it. It's a compile time check. They're talking about calling a method vs. accessing the variable directly. That said ... rarely does anyone need that optimization and there are plenty of *design reasons* for calling a getter rather than accessing the variable. And no, there's no real concept of "const correctness" in Java for the most part. – Brian Roach Jun 18 '13 at 22:46
  • @BrianRoach Yeah, when I read that we 'should always access fields directly' internally, I cringed. I like the flexibility and occasional safety checks I can put into getters and setters. So.. Does that mean that a method marked final is **still** a virtual method? I know that const-correctness is not the same as "final-correctness", if I may call it that, but is it important? Like, "Get it right or God help me I'll murder you with an axe" important? – Justin AnyhowStep Jun 18 '13 at 22:52
  • 2
    Correct. All methods are loaded at runtime by the classloader. The JIT can make improvements by inlining things but it figures that out for itself. – Brian Roach Jun 18 '13 at 23:01
  • 1
    As for "final correctness" .. not really. There's some very valid reasons for using final fields in classes (specifically that you don't have to worry about threads caching different values) but it's not really something you'll see people getting axe-murdery about. – Brian Roach Jun 18 '13 at 23:02
  • http://stackoverflow.com/questions/4912695/what-optimizations-can-i-expect-from-dalvik-and-the-android-toolchain: From Gingerbread on, getters/setters are inlined, so there should be no difference. – assylias Jun 18 '13 at 23:08

1 Answers1

1

Personally, I would recommend not using final for anything other than constants. In quite a few years of development I really haven't seen a good use for final other that static final ... for constants. The final keyword is particularly vexing when it comes to testing - java.net.URL being a final class requires using things like PowerMock if you really want high test coverage.

When in doubt, develop realistic performance tests and profile the two scenarios. If there is no discernible difference, then don't add restrictions like final to your code. Statements like:

direct field access is about 3x faster than invoking a trivial getter

is quite meaningless without some real numbers. If invoking a trivial getter only takes a 20 microseconds, then increasing the cost to 60 microseconds is meaningless. For mobile applications, getters & setters aren't going to cause your performance problems.

Always code for correctness first, readability second, and maintainability after that.

D.Shawley
  • 58,213
  • 10
  • 98
  • 113
  • Erm, non-static final fields in classes, especially when talking about immutable classes you can toss around between threads, are a very good use. – Brian Roach Jun 18 '13 at 23:05
  • Direct field access should not take more than a few nanoseconds, even on a mobile. – assylias Jun 18 '13 at 23:07
  • Correctness.. Like "final-correctness"? I mean, `final` for constants and `static final` is good and all but if overriding a method means changing the behaviour of the method that is expected of classes derived from a base class, wouldn't that be bad? – Justin AnyhowStep Jun 18 '13 at 23:13