2009/5/6 John Cowan <[email protected]>:
>
> On Wed, May 6, 2009 at 11:38 AM, John Wilson <[email protected]> wrote:
>>
>> 2009/5/6 John Cowan <[email protected]>:
>>>
>>> In my language, I need objects which represent Java static methods.
>>
>>
>> How about:
>>
>> public abstract class Function3 {
>> public static final Function3 foo = new Function3() {
>> public Object invoke(Object arg1, Object arg2, Object arg3) {
>> return foo(arg1, arg2, arg3);
>> }
>> };
>
> This is just the one-class-per-function design under a new disguise.
OK.
I have found that the reflection is about an order of magnitude slower
that direct method calls using JDK 6 with the -server option. However
the overhead is quite sensitive to the path from the call site to the
call of Method.invoke(). The JIT appears to like as few stack frames
as possible between the call site and the reflection call.
Object doCall() {
myMethod.invoke();
}
Method getMyCall() {
return myCall;
}
...
doCall() // slower
getMyCall().invoke() // faster
...
In my runtime the dispatch could happen three of four levels down and
returning the Method made a difference. If you are only one level down
you may not see a big advantage.
Also note that the performance of reflection has got better in later
JDKs so if there is a change that your language might have substantial
use on older JVMs then reflection becomes less interesting.
My experience is that you have to spend considerable energy in looking
at the execution paths through the runtime system ensuring that they
are simple (the prime requirement) and short ( a secondary
requirement).
One example:
I have a situation in which monkey patching can change the destination
of a call. In the MetaClass object which determines the behaviour of
the class I have a reference to a MetaClass which is used when there
has been a monkey patch to point to the new behaviour.
Originally I wrote this:
class MetaClass {
private MetaClass actualMetaClass;
public MetaClass() {
this. actualMetaClass = this;
}
public monkeyPatch(MetaClass newMetaClass) {
this.actualMetaClass = newMetaClass;
}
public Object invokeMethod() {
return this.actualMetaClass.doInvokeMethod();
}
public Object doInvokeMethod() {....
This was OK but rewriting the code like this:
class MetaClass {
private MetaClass actualMetaClass = null;
public monkeyPatch(MetaClass newMetaClass) {
this.actualMetaClass = newMetaClass;
}
public Object invokeMethod() {
if (this.actualMetaClass == null) {
return doInvokeMethod();
} else {
return this.actualMetaClass.doInvokeMethod();
}
}
public Object doInvokeMethod() {....
Made a substantial improvement in performance.
It appears that the JIT compiler can do more inlining in the second case.
If I was able (and, in general I'm not) I'd use one class per function
if I wanted the very best performance.
John Wilson
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM
Languages" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en
-~----------~----~----~----~------~----~------~--~---