07.11.10, 14:58, "Rémi Forax" <fo...@univ-mlv.fr>:

>  Works with javac. Do you use it ?

Hm, strange, I thought Netbeans would use the usual javac, but now I guess it 
uses
some API calls to compile files. Because using javac from command line works 
indeed!

>  Why do you want to call a method with a signature which is unknown
>  prior runtime ?
>  You want to write an interpreter ?

Something like that ;)

>  In that case, you can generate bytecode at runtime ane becuase you do that
>  at runtime you know at least the number of parameter.

Well, personally I, can't generate bytecode at runtime ;)
Was I be able to do this, I wouldn't experiment with invokedynamic in first 
place ;)

Can you please comment on invokeVarargs' performance?
An other benchmark (now rewritten to be copy-and-past-able here) shows even
less performance than Method.invoke! (Output is at the end)

Here is the code (in one file):

= = = = = = = = = =
CODE
= = = = = = = = = =

import java.lang.reflect.*;
import java.text.*;
import java.dyn.*;

public class _BenchmarkDyn {

        static abstract class Test {

                final String name;

                Test(String name) {
                        this.name = name;
                }

                abstract void run()
                                throws Throwable;

        }

        final static int N_REPEATS = 10;
        final static long INNER_LOOP = 5 * 1000 * 1000;
        private static long counter = 0;
        private final static Object[] CACHED_EMPTY_ARGS_ARRAY = new Object[]{};
        private final static Method method;
        private final static MethodHandle methodHandle;
        private volatile static int DEOPTIMIZED_INT = 
System.getProperties().size();

        public static void staticMethod() {
                ++counter;
        }

        private static int deoptimizedInt() {
                return DEOPTIMIZED_INT;
        }

        static {
                try {
                        method = _BenchmarkDyn.class.getMethod("staticMethod");
                        Linkage.registerBootstrapMethod("bootstrap");
                        methodHandle = MethodHandles.lookup().findStatic(
                                        _BenchmarkDyn.class, "staticMethod",
                                        MethodType.methodType(void.class));
                } catch (Exception ex) {
                        throw new Error(ex);
                }
        }

        private static CallSite bootstrap(Class<?> declaring, String name, 
MethodType type) {
                System.out.println(declaring + "." + name + " : " + type);
                CallSite cs = new CallSite();
                cs.setTarget(methodHandle);
                return cs;
        }

        private static void doUsual() {
                if (deoptimizedInt() >= 0) {
                        staticMethod();
                }
        }

        private static void doDynSyntax()
                        throws Throwable {
                if (deoptimizedInt() >= 0) {
                        InvokeDynamic.anyName();
                }
        }

        private static void doDynExact()
                        throws Throwable {
                if (deoptimizedInt() >= 0) {
                        methodHandle.invokeExact();
                }
        }

        private static void doDynVarargs()
                        throws Throwable {
                if (deoptimizedInt() >= 0) {
                        methodHandle.invokeVarargs(CACHED_EMPTY_ARGS_ARRAY);
                }
        }

        private static void doReflect()
                        throws Throwable {
                if (deoptimizedInt() >= 0) {
                        method.invoke(CACHED_EMPTY_ARGS_ARRAY);
                }
        }

        private static void tests(Test[] tt) {
                DecimalFormat format = new DecimalFormat("#0.00");
                System.out.println("wait...\n");

                double[] times = new double[tt.length];
                for (int t = 0; t < N_REPEATS; ++t) {
                        for (int i = 0; i < tt.length; ++i) {
                                times[i] += test(tt[i]);
                        }
                }

                System.out.println("done!\n");
                for (int i = 0; i < tt.length; ++i) {
                        System.out.println(tt[i].name + "\n\t" + 
format.format(times[i]) + "s");
                }
        }

        private static double test(Test t) {
                counter = 0;
                long start = System.currentTimeMillis();
                try {
                        t.run();
                } catch (Throwable thr) {
                        throw new Error(thr);
                }
                long end = System.currentTimeMillis();
                return (end - start) / 1000.0;
        }

        public static void main(String... args) {
                Test[] tt = new Test[]{
                        new Test("usual method invocation") {

                                @Override
                                void run()
                                                throws Throwable {
                                        for (long i = 0; i < INNER_LOOP; ++i) {
                                                doUsual();
                                        }
                                }

                        },
                        new Test("invoke dynamic: using 
InvokeDynamic.anyName(...)") {

                                @Override
                                void run()
                                                throws Throwable {
                                        for (long i = 0; i < INNER_LOOP; ++i) {
                                                doDynSyntax();
                                        }
                                }

                        },
                        new Test("invoke dynamic: using invokeExact(...)") {

                                @Override
                                void run()
                                                throws Throwable {
                                        for (long i = 0; i < INNER_LOOP; ++i) {
                                                doDynExact();
                                        }
                                }

                        },
                        new Test("invoke dynamic: using invokeVarargs(...)") {

                                @Override
                                void run()
                                                throws Throwable {
                                        for (long i = 0; i < INNER_LOOP; ++i) {
                                                doDynVarargs();
                                        }
                                }

                        },
                        new Test("reflection: using Method.invoke(...)") {

                                @Override
                                void run()
                                                throws Throwable {
                                        for (long i = 0; i < INNER_LOOP; ++i) {
                                                doReflect();
                                        }
                                }

                        } };

                tests(tt);
        }

}


= = = = = = = = = =
OUTPUT
= = = = = = = = = =
usual method invocation
        0.10s
invoke dynamic: using InvokeDynamic.anyName(...)
        0.14s
invoke dynamic: using invokeExact(...)
        1.05s
invoke dynamic: using invokeVarargs(...)
        7.33s
reflection: using Method.invoke(...)
        0.90s
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to