ProGuard tuning

Hi, I have a question about increasing performance with ProGuard.

If I have this code…


public class Counter {
    private int number = 1;
    public int getNumber() {
        return number;
    }

}
public class Application {
    public static void main(String[] args) {
        Counter c = new Counter();
        System.out.println(c.getCounter());
    }
}

…and then optimize the code with ProGuard, will the code turn out like this then? (I haven’t taken into consideration other optimizations ProGuard might do, such as removing the “c”-variable since it’s only used once.)


public class Counter {
    public int number = 1;
}
public class Application {
    public static void main(String[] args) {
        Counter c = new Counter();
        System.out.println(c.number);
    }
}

Since the getter is very simple and only gives back the value of number this would be a good way to save some operations. If ProGuard does in fact do this I would feel a lot better since I feel like every time I’m making getters and setters I reduce the speed of my application by half. I know the extra method calls won’t be noticable unless it’s done a billion times every second, but still.

ProGuard does have a “Allow access modification” checkbox on the “Optimization” page (using proguardgui.jar) so I would like to believe it does set private attributes to public and replaces simple getters and setters calls with direct access (since it doesn’t really matter to the byte code if a attribute is securely encapsulated or not).

Anyone knows? I’ve been searching around but I can’t find any mentioning concerning this matter on the net.

Edit: Fixed tabs, added a bit of text.

You don’t need that, JVM already does that. It simply inlines very small methods (eg. getters/setters) so the native code ends up with accessing the variable directly. I wouldn’t use any bytecode optimizers as JVM best understands code produced by javac. Sure, it can run any valid bytecode, but it might be slower because it doesn’t match some bytecode optimization patterns in JVM.

The only reasonable way to optimize is to run the whole actual application/game in profiler and check where hotspots are and try to optimize these afterwards. You would be surprised that actual hotspots can be pretty much different than what you’ve thought.

Ah, thanks. I’m glad to hear it, now I don’t have to feel ineffective when I use getters/setters. :slight_smile:

What is/how do I run the application through a profiler? I have never done that before.

Btw, maybe you can help me with another ProGuard question I have up on a different secrion of the forum?
Here’s the link: http://www.java-gaming.org/index.php/topic,20582.0.html

Going back to your original example, I believe proguard would be able to make much more aggressive optimisations in the example case you give.

It would detect that the ‘number’ member is private, and written to only once (in the class constructor), and therefore be able to treat it as a constant - eliminating the member entirely.
The call to getNumber() would be inlinable, which in turn would make the construction of the Counter instance a no-op.
As a result the entire Counter class would become redundant.

So I would hope the code you would end up with would simply be :-


public class Application {
public static void main(String [] args) {
System.out.println(1);
}
}

Ofcourse, the easiest way of checking this is to simply run your code sample through proguard, and then decompile/disassemble it with dj/javap.

Interesting thought, that’s probably true. :slight_smile: I hope.

Still looking for answer to:

[quote]What is/how do I run the application through a profiler? I have never done that before.
[/quote]

You can try NetBeans profiler, I think it’s also included in VisualVM which is part of newer JDKs.

It’s also really easy to download and integrate JProfiler. There is a free trial of 10 days on their website and it took me 10 min to get a button in Eclipse next to the run button that profiles the applet.

If it costs money it’s not for me, and I’d prefer not having to get NetBeans. Found a folder named “profiler2” in Java\jdk1.6.0_11\lib\visualvm but I don’t know how that works.

Is there a way of getting a profiler-button in Eclipse for free? Any alternatives (non-trial)?

Although I’m not a fan of Netbeans, the profiler is pretty good. You don’t need to setup your project in NB either - just run your game from Eclipse as normal and then NB’s dynamic attach method will just give you a list of running Java apps to attach to and profile. Just think of NB as a stand-alone profiler. :wink:

Okay, thanks. I’ll remember that, sounds smart.

I once gave ProGuard a shot by letting it optimize JEmu (which is a seriously CPU performance critical thing). It actually made it slower.

I guess ProGuard can make sense for really simple JVMs (interpreters, J2ME) but a proper JVM like HotSpots seems to perform it’s optimization jobs quite well on its own. Perhaps ProGuard often changes the code in such a way that HotSpot can not make any assumptions anymore to apply its smarter optimization methods.

ProGuard optimizes mostly for file size as far as I know (and it can get .class/.jars quite a bit smaller).

-Ido.