package net.ranides.assira.lambda;

import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.function.IntBinaryOperator;

public class TestMethodPerf {

    public static void main(String... args) throws Throwable {
        // hold result to prevent too much optimizations
        final int[] dummy = new int[4];

        Method reflected = TestMethodPerf.class
                .getDeclaredMethod("myMethod", int.class, int.class);
        final MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodHandle mh = lookup.unreflect(reflected);
        IntBinaryOperator lambda = (IntBinaryOperator) LambdaMetafactory.metafactory(
                lookup, "applyAsInt", MethodType.methodType(IntBinaryOperator.class),
                mh.type(), mh, mh.type()).getTarget().invokeExact();

        testLambda(dummy[1], lambda);

    }

    private static int testLambda(int v, IntBinaryOperator accessor) {
        return accessor.applyAsInt(1000, v);
    }

    private static int myMethod(int a, int b) {
        return a < b ? a : b;
    }
}
