Do any Java compilers or JVMs optimize getter method calls?

Discussion in 'Java' started by david.karr, Sep 3, 2009.

  1. david.karr

    david.karr Guest

    I prefer to reference instance variables through getters, as opposed
    to direct access to them. However, there's "obviously" going to be a
    small time penalty for that. I did some timings in Eclipse, and I
    found direct reads were a tiny fraction faster than through the getter
    call (no surprise), and the difference between the setter and a direct
    write was even smaller (I tested 100000000 iterations, adding up the
    nanosecond intervals of each type of access).

    I'm wondering whether there are any compiler/JVM combinations that
    optimize getter calls to be the same as a direct access? I can see
    from the bytecode in Eclipse that there is no optimization at that
    level, but I don't know if the JVM will do any optimization in some
    cases. It didn't appear to do it in Eclipse, but I don't know if other
    JVMs would act differently.
    david.karr, Sep 3, 2009
    #1
    1. Advertising

  2. david.karr

    Lew Guest

    david.karr wrote:
    > I prefer to reference instance variables through getters, as opposed
    > to direct access to them. However, there's "obviously" going to be a
    > small time penalty for that. I did some timings in Eclipse, and I
    > found direct reads were a tiny fraction faster than through the getter
    > call (no surprise), and the difference between the setter and a direct
    > write was even smaller (I tested 100000000 iterations, adding up the
    > nanosecond intervals of each type of access).
    >
    > I'm wondering whether there are any compiler/JVM combinations that
    > optimize getter calls to be the same as a direct access? I can see
    > from the bytecode in Eclipse that there is no optimization at that
    > level, but I don't know if the JVM will do any optimization in some
    > cases. It didn't appear to do it in Eclipse, but I don't know if other
    > JVMs would act differently.


    You cannot tell optimization from the bytecode, because optimization happens
    in the JVM.

    Doesn't Eclipse use the JVM installed on your system? What JVM is installed
    on your system?

    What options are you passing to the JVM now?

    The most significant optimizations occur with the "-server" option to the
    "java" command (or equivalent). Others are possible. They are documented on
    java.sun.com and elsewhere.

    Methods declared as 'final' tend to be inlined and run faster than methods not
    so qualified.

    When running your benchmarks, let the loop run a bunch of times before you
    start timing. That lets the Hotspot compiler analyze the run and figure out
    what to optimize.

    The tricky thing with Hotspot is that it might inline or enregister or loop
    unroll or compile certain things at some times, then de-optimize them at other
    times depending on the moment-by-moment profile of the execution.

    The compiler (i.e., "javac") tends to have negligible impact on optimization,
    since optimization happens at run time.

    --
    Lew
    Lew, Sep 3, 2009
    #2
    1. Advertising

  3. david.karr wrote:
    > I'm wondering whether there are any compiler/JVM combinations that
    > optimize getter calls to be the same as a direct access?


    From a cursory glance at the OpenJDK source code, hotspot does try to
    inline accessors.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Sep 3, 2009
    #3
  4. david.karr

    David Karr Guest

    On Sep 3, 3:56 pm, Lew <> wrote:
    > david.karr wrote:
    > > I prefer to reference instance variables through getters, as opposed
    > > to direct access to them.  However, there's "obviously" going to be a
    > > small time penalty for that.  I did some timings in Eclipse, and I
    > > found direct reads were a tiny fraction faster than through the getter
    > > call (no surprise), and the difference between the setter and a direct
    > > write was even smaller (I tested 100000000 iterations, adding up the
    > > nanosecond intervals of each type of access).

    >
    > > I'm wondering whether there are any compiler/JVM combinations that
    > > optimize getter calls to be the same as a direct access?  I can see
    > > from the bytecode in Eclipse that there is no optimization at that
    > > level, but I don't know if the JVM will do any optimization in some
    > > cases. It didn't appear to do it in Eclipse, but I don't know if other
    > > JVMs would act differently.

    >
    > You cannot tell optimization from the bytecode, because optimization happens
    > in the JVM.


    Yes, I know, I was just pointing out the bytecode wasn't already pre-
    optimized.

    > Doesn't Eclipse use the JVM installed on your system?  What JVM is installed
    > on your system?


    Yes. I've tested with Sun's 1.5.0_19, 1.6.0_14, and 1.6.0_16.

    > What options are you passing to the JVM now?
    >
    > The most significant optimizations occur with the "-server" option to the
    > "java" command (or equivalent).  Others are possible.  They are documented on
    > java.sun.com and elsewhere.


    I wasn't using "-server" before, but I am now. That's a useful
    change.

    > Methods declared as 'final' tend to be inlined and run faster than methods not
    > so qualified.
    >
    > When running your benchmarks, let the loop run a bunch of times before you
    > start timing.  That lets the Hotspot compiler analyze the run and figure out
    > what to optimize.


    I'm also using both of these strategies. I'm running 100000000 timed
    iterations, so I doubt the warm-up loop is necessary, but I'm doing
    that anyway.

    My measurements show very tiny differences (perhaps .02% total
    difference over all 100000000 iterations). In fact, emphasizing the
    fact that this isn't statistically significant, I saw several runs
    where the "direct" test was slightly slower than the "getter" test.

    If it matters, following this is my test class.

    ------Timings.java----------
    package timings;

    public class Timings {

    private String foo;

    final public String getFoo() {return foo;}
    final public void setFoo(String foo) {this.foo = foo;}

    public static void main(String[] args) {
    Timings timings = new Timings(args);
    timings.go();
    }

    public Timings(String[] args) {}

    private void go() {

    // warmup loop.
    for (int ctr = 0; ctr < 1000; ++ ctr) {
    setFoo(ctr + "");
    getFoo();
    this.foo = this.foo + "";
    }

    int iters = 10000000;

    long totalns;

    totalns = 0;
    for (int ctr = 0; ctr < iters; ++ ctr) {
    setFoo(ctr + "");
    long startTime = System.nanoTime();
    String val = getFoo();
    totalns += (System.nanoTime() - startTime);
    }
    System.out.println("getter[" + totalns + "]");

    totalns = 0;
    for (int ctr = 0; ctr < iters; ++ ctr) {
    setFoo(ctr + "");
    long startTime = System.nanoTime();
    String val = this.foo;
    totalns += (System.nanoTime() - startTime);
    }
    System.out.println("direct[" + totalns + "]");

    totalns = 0;
    for (int ctr = 0; ctr < iters; ++ ctr) {
    long startTime = System.nanoTime();
    setFoo(ctr + "");
    totalns += (System.nanoTime() - startTime);
    }
    System.out.println("setter[" + totalns + "]");

    totalns = 0;
    for (int ctr = 0; ctr < iters; ++ ctr) {
    long startTime = System.nanoTime();
    this.foo = ctr + "";
    totalns += (System.nanoTime() - startTime);
    }
    System.out.println("direct[" + totalns + "]");
    }
    }
    --------------------
    David Karr, Sep 4, 2009
    #4
  5. david.karr

    Roedy Green Guest

    On Thu, 3 Sep 2009 15:31:22 -0700 (PDT), "david.karr"
    <> wrote, quoted or indirectly quoted
    someone who said :

    >I'm wondering whether there are any compiler/JVM combinations that
    >optimize getter calls to be the same as a direct access?


    this is one of the hotspot optimisations. I takes a while for the JVM
    to optimise a routine. It can inline many small routines, not just
    getters.

    If you want it done immediately, you need static optimisation at
    compile time with Jet.
    see http://mindprod.com/jgloss/jet.html

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "People think of security as a noun, something you go buy. In reality, it’s an abstract concept like happiness. Openness is unbelievably helpful to security."
    ~ James Gosling (born: 1955-05-18 age: 54), inventor of Java.
    Roedy Green, Sep 4, 2009
    #5
  6. david.karr

    Karl Uppiano Guest

    "David Karr" <> wrote in message
    news:...
    > On Sep 3, 3:56 pm, Lew <> wrote:
    >> david.karr wrote:


    [...]

    > My measurements show very tiny differences (perhaps .02% total
    > difference over all 100000000 iterations). In fact, emphasizing the
    > fact that this isn't statistically significant, I saw several runs
    > where the "direct" test was slightly slower than the "getter" test.


    Given the infinitesimal advantage of direct calls, it seems you could focus
    your optimization efforts elsewhere to much more advantage. I have always
    found that a solid design is much more effective at achieving high
    performance than speculative optimization. The exception to this rule would
    be if profiling revealed that you were spending an inordinate amount of time
    calling getters.
    Karl Uppiano, Sep 4, 2009
    #6
  7. david.karr wrote:

    > I'm wondering whether there are any compiler/JVM combinations that
    > optimize getter calls to be the same as a direct access?


    As already mentioned this is done by the Hotspot. Maybe the
    Hotspot inlines faster, if you declare the getter-method
    final. On the other hand, why do you bother with this kind
    of optimization? Do you have real performance-problems?

    If not, just let it be the way it is (with getters and setters)
    and concentrate on something else. I had to solve a couple
    of problems and never it was a simple getter that caused the
    problem but some inefficient algorithm.


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
    Lothar Kimmeringer, Sep 4, 2009
    #7
  8. Karl Uppiano wrote:

    > I have always
    > found that a solid design is much more effective at achieving high
    > performance than speculative optimization. The exception to this rule would
    > be if profiling revealed that you were spending an inordinate amount of time
    > calling getters.


    And if that is the case, the use of a cached value (assuming
    that the getter-method returned the same value all the time)
    should be a much better solution than changing the access
    from the call of a getter to the direct access of the field.


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
    Lothar Kimmeringer, Sep 4, 2009
    #8
  9. David Karr <> wrote:
    > If it matters, following this is my test class.
    > ------Timings.java----------
    > package timings;
    > public class Timings {
    > [...]
    > // warmup loop.
    > for (int ctr = 0; ctr < 1000; ++ ctr) { ... }


    Good, but I'd spend like 100000 iterations to warmup, or even
    place two loops ... Probably not more than Voodoo, but I think
    it helped in a previous case for me. (I had a loop over the
    actual measurement loops, and the first two complete runs of
    inner loops took noticeably more time than each of the following
    ones)

    > int iters = 10000000;
    > for (int ctr = 0; ctr < iters; ++ ctr) {
    > setFoo(ctr + "");
    > long startTime = System.nanoTime();
    > String val = getFoo();
    > totalns += (System.nanoTime() - startTime);
    > }


    I wouldn't do it that way, but rather take the nanos before and
    after the inner loop. The loop-overhead is probably less than the
    time-taking overhead. If it isn't then differences of getter-
    timings compared to loop-overhead makes the matter even more moot.

    Also, you could make the attribute an int and assign it the current
    loop-counter. that will reduce the overhead for generating a new
    value to set before getting it.

    PS: Since a recent "adventure" with an oracle-sql query, my trust in
    automatic optimizations is currently lower than ever. (although java-
    optimizations have nothing to do with (absent) oracle-optimizations)
    Andreas Leitgeb, Sep 4, 2009
    #9
  10. david.karr

    Roedy Green Guest

    On Thu, 3 Sep 2009 16:32:57 -0700 (PDT), David Karr
    <> wrote, quoted or indirectly quoted
    someone who said :

    >
    >Yes, I know, I was just pointing out the bytecode wasn't already pre-
    >optimized.


    One of the amusing things is if you optimise the byte code it can make
    the code SLOWER, because Hotspot and other optimisers don't have the
    clutzy standard patterns to recognise.

    I poked around quite a bit at the assembler generated by Jet. I was
    blown away by what it did. It was faster than any sane human would
    write. It took into account not just the official number of cycles
    per instruction, but the internal parallelisation of the chips and the
    pipelines.

    Unfortunately, the Jet people were freaked by this and removed the
    tool to display the assembler code. They sell Jet not so much as an
    optimiser as an obfuscator. They felt my discussion of how it worked
    inside make it look as if it were easy to disassemble, which it most
    definitely is not.



    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "People think of security as a noun, something you go buy. In reality, it’s an abstract concept like happiness. Openness is unbelievably helpful to security."
    ~ James Gosling (born: 1955-05-18 age: 54), inventor of Java.
    Roedy Green, Sep 4, 2009
    #10
  11. david.karr

    Lew Guest

    Lothar Kimmeringer wrote:
    > Karl Uppiano wrote:
    >
    >> I have always
    >> found that a solid design is much more effective at achieving high
    >> performance than speculative optimization. The exception to this rule would
    >> be if profiling revealed that you were spending an inordinate amount of time
    >> calling getters.

    >
    > And if that is the case, the use of a cached value (assuming
    > that the getter-method returned the same value all the time)
    > should be a much better solution than changing the access
    > from the call of a getter to the direct access of the field.


    This is an optimization of which HotSpot is capable.

    --
    Lew
    Lew, Sep 4, 2009
    #11
  12. david.karr

    Roedy Green Guest

    On Fri, 04 Sep 2009 12:00:25 +0200, Michal Kleczek <>
    wrote, quoted or indirectly quoted someone who said :

    >
    >The compiler cannot do any inlining because called method implementation is
    >not actually known until runtime (IOW the class file containing method
    >implementation can be replaced after compilation).


    Hotspot inlines even non final methods. If a class gets loaded that
    overrides a method, it undoes the inlining on the fly -- talk about
    trapeeze act without a net. It can do this even if it is the middle
    of executing a method at the time. I have a hard time believing this
    could possibly work.

    A byte-code compiler could inline final methods, but not non-final
    ones.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "People think of security as a noun, something you go buy. In reality, it’s an abstract concept like happiness. Openness is unbelievably helpful to security."
    ~ James Gosling (born: 1955-05-18 age: 54), inventor of Java.
    Roedy Green, Sep 4, 2009
    #12
  13. Lew wrote:

    > Lothar Kimmeringer wrote:
    >> Karl Uppiano wrote:
    >>
    >>> I have always
    >>> found that a solid design is much more effective at achieving high
    >>> performance than speculative optimization. The exception to this rule would
    >>> be if profiling revealed that you were spending an inordinate amount of time
    >>> calling getters.

    >>
    >> And if that is the case, the use of a cached value (assuming
    >> that the getter-method returned the same value all the time)
    >> should be a much better solution than changing the access
    >> from the call of a getter to the direct access of the field.

    >
    > This is an optimization of which HotSpot is capable.


    To be honest, I don't care what the HotSpot is capable to do.
    If a profiler shows me that the call of a specific get-method
    is the reason why some code of mine takes significantly longer
    than it should be, I don't hope that the HotSpot might take
    care of it but do it for myself.

    Or in other (well known) words: Premature optimization is the
    root of all evil. David's giving a good example. Using a direct
    field-access instead of a getter-method will lead to a lot of
    trouble if at a later point of time you need additional logic
    before handing out the result, e.g. cloning an internal array
    instead of giving out the original, etc.


    Regards, Lothar
    --
    Lothar Kimmeringer E-Mail:
    PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

    Always remember: The answer is forty-two, there can only be wrong
    questions!
    Lothar Kimmeringer, Sep 4, 2009
    #13
  14. david.karr

    David Karr Guest

    On Sep 3, 9:10 pm, "Karl Uppiano" <> wrote:
    > "David Karr" <> wrote in message
    >
    > news:...
    >
    > > On Sep 3, 3:56 pm, Lew <> wrote:
    > >> david.karr wrote:

    >
    > [...]
    >
    > > My measurements show very tiny differences (perhaps .02% total
    > > difference over all 100000000 iterations).  In fact, emphasizing the
    > > fact that this isn't statistically significant, I saw several runs
    > > where the "direct" test was slightly slower than the "getter" test.

    >
    > Given the infinitesimal advantage of direct calls, it seems you could focus
    > your optimization efforts elsewhere to much more advantage. I have always
    > found that a solid design is much more effective at achieving high
    > performance than speculative optimization. The exception to this rule would
    > be if profiling revealed that you were spending an inordinate amount of time
    > calling getters.


    You've missed the point, perhaps because I didn't make it clear why I
    was experimenting with this. I prefer calling getters instead of
    direct access. I did this research because I expect to be called on
    this in code reviews with claims that calling getters would be slower
    than direct access.
    David Karr, Sep 4, 2009
    #14
  15. david.karr

    Lew Guest

    David Karr wrote:
    > You've missed the point, perhaps because I didn't make it clear why I
    > was experimenting with this.  I prefer calling getters instead of
    > direct access.  I did this research because I expect to be called on
    > this in code reviews with claims that calling getters would be slower
    > than direct access.
    >


    If anyone did "call" you on using accessor methods based on some
    imagined performance penalty, even without benchmarking yourself you
    can counteract such a blatantly ridiculous criticism by pointing out
    how blatantly ridiculous such a criticism is.

    Start by asking them what proof they have that accessor methods are
    even slower than direct access, let alone sufficiently slower that it
    matters, then ask how such an unproven difference in speed compensates
    for the loss of maintainability and encapsulation. Then suggest that
    their skills would be of better use in an environment where they're
    mostly asking, "Would you like fries with that?"

    --
    Lew
    Lew, Sep 4, 2009
    #15
  16. david.karr

    Lew Guest

    Lew wrote:
    >> If anyone did "call" you on using accessor methods based on some
    >> imagined performance penalty, even without benchmarking yourself you
    >> can counteract such a blatantly ridiculous criticism by pointing out
    >> how blatantly ridiculous such a criticism is.

    >


    Eric Sosman <> wrote:
    >      In mathematics, this technique is known as Proof by Assertion.
    > (Some know it as the Because I Said So argument.)
    >


    Mitigated in this particular instance by the fact that the argument
    the OP fears is actually blatantly ridiculous. Proof of the blatant
    ridiculosity was left as an exercise. (A very popular pedagocical
    dodge in all my old math textbooks.)

    Lew:
    >> Start by asking them what proof they have that accessor methods are
    >> even slower than direct access, let alone sufficiently slower that it
    >> matters, then ask how such an unproven difference in speed compensates
    >> for the loss of maintainability and encapsulation.  Then suggest that
    >> their skills would be of better use in an environment where they're
    >> mostly asking, "Would you like fries with that?"

    >


    Eric:
    >      In debate, this technique is known as Force the Adversary to
    > Hold His Ground No Matter What.  (Some know it as the Feel-Good
    > Moment Before the Roof Caves In.)
    >


    In the Bible it's called, "Never answer a fool in terms of his folly,
    lest he think himself wise." Personally I get so disgusted with
    people in code reviews trying to get me to do the wrong thing that I
    lose the willingness to treat them as rational beings.

    Don't misconstrue. Plenty of people disagree with me and can provide
    intelligent reasoning for doing so. This newsgroup is a great
    example. That is not a problem. It's people trying to make really
    stupid cases, like, "You shouldn't use accessor methods in Java
    because direct references to member variables is faster," that gets
    me.

    You ignored the expressed reasoning behind my points, that the
    putative advantage of direct variable access asserted by the stupid
    reviewers must be proven to exist at all, let alone to a degree that
    justifies the sacrifice of accessors' advantages. Since you're good
    at identifying the names for rhetorical dodges, what should such
    omission be called?

    --
    Lew
    Lew, Sep 4, 2009
    #16
  17. david.karr

    David Karr Guest

    On Sep 4, 10:52 am, Lew <> wrote:
    > David Karr wrote:
    > > You've missed the point, perhaps because I didn't make it clear why I
    > > was experimenting with this.  I prefer calling getters instead of
    > > direct access.  I did this research because I expect to be called on
    > > this in code reviews with claims that calling getters would be slower
    > > than direct access.

    >
    > If anyone did "call" you on using accessor methods based on some
    > imagined performance penalty, even without benchmarking yourself you
    > can counteract such a blatantly ridiculous criticism by pointing out
    > how blatantly ridiculous such a criticism is.
    >
    > Start by asking them what proof they have that accessor methods are
    > even slower than direct access, let alone sufficiently slower that it
    > matters, then ask how such an unproven difference in speed compensates
    > for the loss of maintainability and encapsulation.  Then suggest that
    > their skills would be of better use in an environment where they're
    > mostly asking, "Would you like fries with that?"


    I started this experiment because I don't like to ask questions that I
    don't know the answer to :), if I can help it. If I was challenged on
    this, I would ask "have you measured it?". When they answer "no, it's
    obvious", that's when I can say "I've measured it and researched it,
    and it's not obvious."
    David Karr, Sep 4, 2009
    #17
  18. david.karr

    Lew Guest

    Lew wrote:
    >> You ignored the expressed reasoning behind my points, that the
    >> putative advantage of direct variable access asserted by the stupid
    >> reviewers must be proven to exist at all, let alone to a degree that
    >> justifies the sacrifice of accessors' advantages.  Since you're good
    >> at identifying the names for rhetorical dodges, what should such
    >> omission be called?

    >


    Eric Sosman wrote:
    >      "Praeterition."
    >


    What a fabulous word!

    As a rhetorical device, that usually involves bragging about the
    omission, as the example at
    <http://en.wiktionary.org/wiki/Praeterition>
    shows.

    The rhetorical device of praeterition also emphasizes the "omitted"
    part, as in, "I do not intend to draw attention to the compelling and
    irrefutable logic presented to support the rejection of bad advice in
    code reviews. Instead I will focus on the rhetorical devices used to
    express that logic."

    --
    Lew
    Lew, Sep 4, 2009
    #18
  19. david.karr

    Lew Guest

    Roedy Green wrote:
    >> Hotspot inlines even non final methods. If a class gets loaded that
    >> overrides a method, it undoes the inlining on the fly -- talk about
    >> trapeeze act without a net. It can do this even if it is the middle
    >> of executing a method at the time. I have a hard time believing this
    >> could possibly work.


    Michal Kleczek wrote:
    > I think OP meant javac compiler not HotSpot.


    Regardless. His answer lies in HotSpot, not javac.

    --
    Lew
    Lew, Sep 5, 2009
    #19
  20. david.karr

    Eric Sosman Guest

    [OT] Re: Do any Java compilers or JVMs optimize getter method calls?

    Lew wrote:
    > [...]
    > Eric Sosman wrote:
    >> "Praeterition."
    >>

    >
    > What a fabulous word!


    Tip the hat to my high school Latin teacher, Theodore
    Hersey. He had a penchant for trying to simplify things by
    explaining them in terms of things more abstruse. So when
    we came to the verb "praetereo" (I pass over), he told us
    tenth-graders, ever so soothingly, that this was where we got
    the familiar English word "praeterition."

    We were oh! so! grateful ...

    (This is the same guy who explained a construction called
    the "passive periphrastic" by telling us "Don't worry about that
    word `periphrasis;' it's just Greek for `circumlocution'").

    (On the more vital side, he promised an "A For Life" to
    anyone who could render "Them ain't clams, them's quahogs"
    in idiomatic Latin. Nobody ever collected.)

    --
    Eric Sosman
    lid
    Eric Sosman, Sep 5, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page