On Tue, Nov 10, 2009 at 9:01 AM, logicmoo@gmail.com wrote:
Alessio, Excellent Work!
Your .patch is what I meant.
Thanks!
when compiled it is translated as a direct call to the static method, without passing through the symbol, which is faster than now
Perfect - Yeah
A Side note:
When interpreted or passed as a higher-order function an InlinedPrimitive calls the static method through reflection, resulting in slower performance than now.
I wrote a workaround for this into LarKC because of the performance degradation.
So later on.... Like after we have everything working/vetted calling static inlines as much as possible. And using InlinePrimtives to call reflection...
We'll have some options like: "FixedArityFunctor":
http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/too...
What I did was created a new Class via ASM that contains a single execute(a,b,c,d,e,f) signature per "args used". That simply calls the static method .
So in InlinePrimitive later suplimented with some extras like:
//The methodWith0Args - methodWithNArgs is what that .java url above generates. LispObject execute() { return methodWith0Args.evaluate(); } LispObject execute(LispObject a0) { return methodWith1Args.evaluate(a0); } LispObject execute(LispObject a0,LispObject a1) { return methodWith2Args.evaluate(a0,a1); } etc
Figured I should mention the "FixedArityFunctor" so we dont get scared off by any performance degration of higher level calls before we learn all the benefits of inlining static functions!
Ok, I'm not sure I followed everything, but consider also that the implementation through reflection is the default one, for convenience, but you can still override the various execute() methods and call the static method directly (of course, you have to make sure the method you call is the same as the one you pass in the constructor, or things start to behave differently in interpreted vs compiled code and that's definitely not good :D). Something like
new InlinedPrimitive(My.class, "myMethod", ...) { public LispObject execute(LispObject arg) { return My.myMethod(arg); } }
The class I posted lacks the constructors taking the class and the method, because I have been lazy ;), but they can easily be added - with the caveat that, since the call to super() must be the first and for Function super() sometimes (always?) installs the function in a symbol (iirc), if you pass a wrong class/method to InlinedPrimitive and as a result an exception is thrown, you'll have a symbol pointing to an invalid function.
Bye, Ale