Few questions about invokeDynamic
assembling signals
assembling.signals at yandex.ru
Sun Nov 7 09:48:35 PST 2010
07.11.10, 14:58, "Rémi Forax" <forax at 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
More information about the mlvm-dev
mailing list