I'm testing how much performance Method Handles (delivered with Java 7) have against Java Reflection and Mirror (A fluent API to work with reflection - http://projetos.vidageek.net/mirror/mirror/). So I don't know if I wrote the test code properly.
I use JHM tool to make this tests, and I shared the code and results in my gist: https://gist.github.com/garcia-jj/057dcab7f388e5cb42d1
I cached in setup method all lookups to increase performance.
The final time is almost equals between Reflection and Method Handles.
So my question is: my test is right? There is some problems to cache method lookup in my application? Or I need to lookup always when I need to use invokeExact? If I don't create the cache the performance is too low.
Thank you
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class Reflecting {
    // testing method handle
    private MethodHandle mhConcat;
    private MethodHandle mhHashCode;
    // testing reflection     
    private Method rconcat;
    private Method rhashcode;
    // testing mirror api
    private MethodHandler mrConcat;
    private MethodHandler mrHashcode;
    @Setup
    public void setup() throws Exception {
        mhConcat = publicLookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
        mhHashCode = publicLookup().findVirtual(Object.class, "hashCode", methodType(int.class));
        rconcat = String.class.getDeclaredMethod("concat", String.class);
        rhashcode = String.class.getDeclaredMethod("hashCode");
        mrConcat = new Mirror().on((Object) "x").invoke().method("concat");
        mrHashcode = new Mirror().on((Object) "xy").invoke().method("hashCode");
    }
    @GenerateMicroBenchmark
    public void invoke(BlackHole bh) throws Throwable {
        bh.consume((String) mhConcat.invokeExact("x", "y"));
        bh.consume((int) mhHashCode.invokeExact((Object) "xy"));
    }
    @GenerateMicroBenchmark
    public void reflect(BlackHole bh) throws Throwable {
        bh.consume(rconcat.invoke("x", "y"));
        bh.consume(rhashcode.invoke("xy"));
    }
    @GenerateMicroBenchmark
    public void mirror(BlackHole bh) throws Throwable {
        bh.consume(mrConcat.withArgs("y"));
        bh.consume(mrHashcode.withoutArgs());
    }
}
 
     
    