Which methods DOES client-jvm inline?

Hi there!

The hotspot-docs says that client-jvm only does very limmited inlining, I assume this is because it has not the ability to deoptimize something.

I use proguard which does closwed-world optimizations and declares everything as final which is not overridden any more - and this is quite ok cause my applet does not load any classes at runtime.

Will those compiled methods be inlined?

Thanks in advance, lg Clemens

Final is no longer necessary to achieve high performance, and should be avoided in all cases unless you have a really good reason for it.

How much faster is your applet with and without the final-ing?

Why should final’ing be avoided under any cases?

It seems you have not read my post carefull and just shot out an std-answer.
Final should be only avoided because it leds to bad code, but if a optimizer does this for you you till get more performance.

In fact it decreases the work the jvm has to do at method-lookup since final tells the jvm that no overridden methods except the actual are there and that no method-class matching needs to be done!
Another benefit is, that JVM knows at jit-compile-time that no classes may override this method later and not deoptimizing is needed.

Now, lets go back to topic:

Does anybody know which method-types client-jvm can inline and where are the limitations?

Thanks in advance, lg Clemens

[quote]Why should final’ing be avoided under any cases?
[/quote]
Because java is dynamically-linked, always. Which means that someone can compile against your source, extend a class, and then when they try to run it using your binary it will break.

That’s not a great example, but the simplest I can think of off the top of my head :).

Hence it’s bad practice to final things unless you really, really mean it (i.e. there is no way this method could ever be deliberately overridden without causing grave problems - e.g. sun final’d some methods in AWT which allocated or interacted with native memory, which would cause nasty crashes in the JVM if you overrode them. I know because I found some other ways to get at them :)).

As I asked before: what performance difference do you see? My guess is the answer is “none at all”. It used to be necessary to final methods to get them to become candidates for certain optimizations, e.g. inlining, in the JVM, but this was fixed quite a while ago (3 years ago? 5 years ago?).

I’m sorry that you thought I was trotting out a knee-jerk answer; if you are genuinely seeing performance differences, then that’s wonderful. But unless you’re doing some funky stuff I very much doubt you are.

I’m wary of making such statements until I’ve checked what the current JVM actually does in these situations. For instance, the recent addition of co-variant types and parametric function despatch means this part of any JVM is likely to (have recently been) be re-architected.

Maybe you’re right and it’s still an issue. Do you know this? (I ask out of interest - I haven’t had time yet to go trawling to try and find some docs from Sun on what they’ve done about this in 1.5; the fact that I’ve spent years looking for similar docs from them about their NIO implementation and still not found any puts me off looking unless someone else finds it first ;D).

Again, are you sure? This is somethign that used to be an issue, but I’m not convinced it matters any more (unless you do something very unusual in your programming)

Yes, of course. For libs or dynamic stuff final is always bad - its just stupid to do such bad optimizations for just a few % of speed increase.

Why I do is using a bytecod eoptimizer on a closed-world-applikation (everything is in, only limmited class-loading, not used at library at all), that means I give ione jar into it and what comes out is a jar which is 5% faster on client-jvm and much smaller (I use proguard).

Btw. yes I know the client-jvm cannot inline polymorphic methods, because it cannot deoptimize inlined stuff when e.g. a new class which overrides the inlined method later is loaded via Class.forName(),
This is only available on server-jvm which is from the technical point of view a masterpiece! (btw. IBM performs still better on general server apps…).

lg Clemens

Four pertinent figures:
a. performance after Sun compile
b. ditto, but running on server VM for a while (takes up to 5-10 minutes to really get going)
c. performance after optimizer ONLY adds final’s
d. performance after full optimization.

I’m not sure, but it sounds like you’ve quoted the ratio from a to d, and it sounds painfully small? Or…was that the difference from a to c?

Also, how are you measuring “performance”? Are we talking average FPS over a certain period, or something completely different?

Just chiming in to defend the use of ‘final’ on local variables (including method params). Using it can lead to more bug free code as the compiler will catch any attempts to accidently overwrite variables which should not be overwritten.

Will.

[quote]Just chiming in to defend the use of ‘final’ on local variables (including method params).
[/quote]
Interesting idea: compiler should implicitly make all method params final. /me wonders why the JLS doesn’t mandate this.

Well…that’s what it’s there for, isn’t it. But usually such situations are very rare - if you have something you don’t want to be variable, you’re not going to put it in a “variable” :).

The more compilers try to help me, the more they seem to get in the way… a pox on the final keyword. And further poxes on private and protected. And a little bit of extra pox on generics for being so shit.

Cas :slight_smile:

[quote]The more compilers try to help me, the more they seem to get in the way… a pox on the final keyword. And further poxes on private and protected. And a little bit of extra pox on generics for being so shit.

Cas :slight_smile:
[/quote]
LOL. “final” these days is mainly for library writers (one of the very few features of java to support library-writing).

For instance, the threading models in the GrexEngine are partially extensible, but certain core methods (including the “run” method) are far too complex and dangerous for a customer/developer to override (there’s no valid reason you’d want to, because any change you make would need you to replace the entire threading model anyway - at which point you should just use your own separate classes, because the GrexEngine is coded to accept different modular models!).

By making them final, we can allow the classes containign them to be extended, without fear of accidental damage. There are even a couple of methods that were NOT final for a long time (including run(), originally) but we had some nasty hard to trace bugs in user code that eventually came down to someone accidentally overriding run(). We changed it, bug fixed, no-one complained - and now it can’t happen in future).

This is especially useful for “base” classes with complex behaviour. You can make something akin to an Applet (i.e. a base class that comes with funky features not found elsewhere) whose only purpose is to be customized by the user in one or two particular ways, and be sure they don’t **** it up. If the base class is simple/trivial it’s probably unnecssary (and hence should be avoided) but if there are complex things going on under the hood then there are often interdependent methods you want to make final. If there’s a chance some behaviour could conceivably be worth overriding, then you refactor that out into a non-final method.

So…it’s a bit like synchronized: you can use it all over the place and still compile OK, but using it properly requires considerable thought and planning. Not recommended unless you really need it (but when you do, it’s indispensable!)

It is a help I think and more important if one of those params will be modified within the method.

I got the suggestion from a book, and I use it regularly. It does look a little odd at first since one is not used to it. I’ve had a few mistakes caught by employing this practice, mistakes which would have been quite “fun” to hunt down otherwise.

Will.

I use this very often in conjunction with abstract (or not) protected methods that the client can override.


public abstract SomeClass {
    public final void anAction() {
        // here, do something important that *must* be done
        
        // now let the subclass have a go
        doAnAction();
    }

    protrected abstract void doAnAction();
}

Of course, if it’s not essential that the subslcass override the do method then it need not be abstract. But final is excellent in this situation for preventing the subclass from overrding anAction and forgetting to call the super’s version.

I think there is some confusion over what fhte final key word means.

FInal is a syntactic issue. It is NOT a “compiler derictive” and in of itself implies nohting abbout how the compiler will handle the code.

It exists almost purely for security reasons. There are security situatiosn under which one peice orf code depends on\ the precide implementation of another and allowing the rotine to be sub-classed and changed would create a security hole.

It limits the utility of the cde so i nalmost all other siutations it shoudl be avoided.

NOW some early compilers used the knwqoeldge that code was "final’ to help the optimize. This is no longer the case with modren compilers. Instead they do run-time tarcking to see if methdos are used in a ‘final’ fashion (nevre sub-classed.)