Java reflection. Does calling a method give a result faster than fields?

I was microbenchmarking some kind of code (please be beautiful) and came across this puzzle: when reading a field using reflection, calling the getter method is faster than reading the field.

Simple testing class:

private static final class Foo { public Foo(double val) { this.val = val; } public double getVal() { return val; } public final double val; // only public for demo purposes } 

We have two reflections:

 Method m = Foo.class.getDeclaredMethod("getVal", null); Field f = Foo.class.getDeclaredField("val"); 

Now I call two reflections in the loop, invoke in the method and get in the field. The first start is performed to warm up the virtual machine, the second start is performed using 10M iterations. Calling a method sequentially is 30% faster, but why? Note that getDeclaredMethod and getDeclaredField are not called in a loop. They are called once and are executed on one object in a loop.

I also tried some minor variations: made the field non-confidential, transitional, non-public, etc. All of these combinations resulted in statistically similar performance.

Edit: This is on WinXP, Intel Core2 Duo, Sun JavaSE build 1.6.0_16-b01, running under jUnit4 and Eclipse.

+4
source share
3 answers

My educated guess would be the difference in how getDeclaredField and getDeclaredMethod methods are implemented: although each time it is called, getDeclaredField will have to check the type and size of the variable to return the actual object or primitive type, getDeclaredMethod will return a pointer to the same a method that takes care of the rest statically.

Edit

My explanation is similar: the method is stored in memory only once for each class, while each instance of the object can have different property values. When you get a property value by making a method call (still using only the method pointer), the compiler optimized the method to access the parameter, knowing the exact hierarchy of classes, etc. When you get the property value using "get", you allow reflections do the job of the getter method, and obviously there can be no compiler optimization.

+3
source

In your microobject, the method call is faster due to the optimization made by the JVM / Hotspot with your loop.

Change your microbenchmak:

Make a loop in which: read the value of Reflection, then increase 1 (for example), and then assign the same field via Reflection. And outside the loop, do the final read and System.out.println it ...

Follow the two options (Field vs Method), and you will see that the real difference is the opposite: method calls are actually 30-40% slower.

Hello

+1
source

does this also mean that double d = Foo.getVal() is 30% faster than double d = Foo.val ?

0
source

Source: https://habr.com/ru/post/1334191/


All Articles