Nov. 29, 2006, 11:20 a.m.

Dear Eclipse: Please Stop Telling People Synthetic Method Access is Bad

I was going through my eclipse compiler settings and decided to turn on this synthetic access warning thing again. I mean, it makes sense that accessing a private method in another class might be slow, but I want to measure how slow.

In my quest for understanding the actual impact of this, I figured I'd test to see how much faster all of my code would be by avoiding synthetic accessors.

My results, in summary, indicate that synthetic method access used to be slightly slower, but it's now considerably faster (at least on my JVMs). Synthetic field access is still considerably slower. The detailed results follow (all on OS X/intel):

[compiling with 1.3]
[decompiling]
[running with 1.3 -server]
Running 1000000 iterations 5 times each.
pkg visible field: [1271, 1256, 1231, 1238, 1245]
pkg visible method: [1609, 1635, 1629, 1613, 1637]
synth field: [1686, 1661, 1663, 1658, 1668]
synth method: [1776, 1781, 1766, 1776, 1781]

[compiling with 1.4]
[decompiling]
[running with 1.4 -server]
Running 1000000000 iterations 5 times each.
pkg visible field: [3383, 3395, 3402, 3375, 3388]
pkg visible method: [3295, 3385, 3315, 3296, 3298]
synth field: [3383, 3421, 3442, 3381, 3381]
synth method: [3314, 3346, 3352, 3298, 3308]

[compiling with 1.5]
Note: SyntheticAccess.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
[decompiling]
[running with 1.5 -server]
Running 1000000000 iterations 5 times each.
pkg visible field: [3124, 3313, 3179, 3175, 3128]
pkg visible method: [4054, 4057, 4315, 4339, 4058]
synth field: [7156, 7260, 7206, 7342, 7117]
synth method: [2969, 2923, 3068, 3049, 2961]

[compiling with 1.6]
Note: SyntheticAccess.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
[decompiling]
[running with 1.6 -server]
Running 1000000000 iterations 5 times each.
pkg visible field: [3042, 3045, 3069, 3064, 3057]
pkg visible method: [6215, 6238, 6129, 6146, 6133]
synth field: [7123, 7127, 7137, 7115, 7176]
synth method: [3145, 3089, 3155, 3107, 3114]

So, what's changed? I don't quite know. I did see that when I compiled code for 1.3 and ran it under 1.5, although it ran much, much faster, it had the same relative performance profile as 1.3. That is, synthetics were slower. Jad didn't really leave me any clues. It seems to be doing almost exactly the same thing with just a few op codes switched around.

The most bizarre thing, though, is that when I run code compiled with 1.3 under 1.4, 1.5, or 1.6, it's twenty to forty times faster than code compiled with 1.4+. I won't speculate on this.

I think a lot of this is micro-optimization, though. You can certainly disable the warning in eclipse, but it is global for both method and field access. That means that in order to be informed of a type of access that's about 2x slower (synthetic field), you have to deal with being warned about an access that's about 2x faster (synthetic method).

If you want to run some of these tests yourself, you can download the code I used to run them.

blog comments powered by Disqus