bing ran | 1 Jun 2004 15:16

RE: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?

Incidentally I have an experimental  implementation of early binding _only
for_  calling java libs (JDK and third party jars) on my local machine. I'm
avoiding static dispatching for Groovy classes due to the invokeMethod issue
(also the behavior of Groovy method call in general). GDK extensions are
excluded too.  I'm seeing performance improvement in the range of 100-200%
in my test cases. The mechanism is the same as suggested by you guys: method
invocations on  variables defined with explicit type info are candidates for
early bindings if the invocation can be unambiguously mapped to a method of
the declaring class. 

The test case I'm using is:

class MethCall {
    i = 0;
    count = 100000
    String ori = 'hello'  	// <== statically typed
    String str  = ori		// <== statically typed
    c = 0
    cc = 0
    static int calls = 0
    func() {
        start = System.currentTimeMillis();	// early binding
        while (i++ < count) {		// ++ and < operations can be
optimized too, but not yet
             cc = str.charAt(0);		// early binding
             c = ori.length()		// early binding
        }
        end = System.currentTimeMillis();

        println "run ${count} times in ${end - start} millis"
(Continue reading)

John Wilson | 1 Jun 2004 15:43
Picon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On 1 Jun 2004, at 14:16, bing ran wrote:

> Incidentally I have an experimental  implementation of early binding 
> _only
> for_  calling java libs (JDK and third party jars) on my local 
> machine. I'm
> avoiding static dispatching for Groovy classes due to the invokeMethod 
> issue
> (also the behavior of Groovy method call in general). GDK extensions 
> are
> excluded too.  I'm seeing performance improvement in the range of 
> 100-200%
> in my test cases. The mechanism is the same as suggested by you guys: 
> method
> invocations on  variables defined with explicit type info are 
> candidates for
> early bindings if the invocation can be unambiguously mapped to a 
> method of
> the declaring class.
>
> The test case I'm using is:
>
> class MethCall {
>     i = 0;
>     count = 100000
>     String ori = 'hello'  	// <== statically typed
>     String str  = ori		// <== statically typed
>     c = 0
>     cc = 0
(Continue reading)

John Wilson | 1 Jun 2004 16:04
Picon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On 1 Jun 2004, at 14:43, John Wilson wrote:

> In the case of a Java class subclassing a Java class (other than 
> Object) and implementing GroovyObject there's not much that can be 
> done as far as I can see. I'd be perfectly happy if programmers were 
> that the dynamic calls would not be made if the object was cast to the 
> superclass in Groovy.
>

Sorry that was gibberish :)

In the case of a Java class subclassing a Java class (other than 
Object) and implementing GroovyObject there's not much that can be done 
as far as I can see. I'd be perfectly happy if programmers were told 
that the dynamic calls would not be made if the object was cast to the 
superclass in Groovy.

makes slightly more sense.

John Wilson
The Wilson Partnership
http://www.wilson.co.uk

bing ran | 1 Jun 2004 17:09

RE: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?

John, your proposal makes sense to me, and identifies a hole in my current code, although we do not necessarily need to bar classes from having methods of the same signature without declaring to implement the GroovyObject interface.- they just get ignored. As a matter of fact, I have yet to find how to define a Groovy class that does NOT implement GroovyObject:)

I'll add checks to my code so that any messages sent to GroovyObject will take late binding - Groovy means dynamic anyway.

Let's see how it goes:)

Thanks!
 
--bing




: John Wilson [mailto:tug-GwqJ/HqVibzQXOPxS62xeg@public.gmane.org]
Sent: Tuesday, June 01, 2004 9:43 PM
To: dev-i9PBDF1N6cxnkHa44VUL00B+6BGkLq7r@public.gmane.org
Subject: Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On 1 Jun 2004, at 14:16, bing ran wrote:

> Incidentally I have an experimental  implementation of early binding
> _only for_  calling java libs (JDK and third party jars) on my local
> machine. I'm avoiding static dispatching for Groovy classes due to the
> invokeMethod issue (also the behavior of Groovy method call in
> general). GDK extensions are excluded too.  I'm seeing performance
> improvement in the range of 100-200% in my test cases. The mechanism
> is the same as suggested by you guys:
> method
> invocations on  variables defined with explicit type info are
> candidates for early bindings if the invocation can be unambiguously
> mapped to a method of the declaring class.
>
> The test case I'm using is:
>
> class MethCall {
>     i = 0;
>     count = 100000
>     String ori = 'hello'      // <== statically typed
>     String str  = ori         // <== statically typed
>     c = 0
>     cc = 0
>     static int calls = 0
>     func() {
>         start = System.currentTimeMillis();   // early binding
>         while (i++ < count) {         // ++ and < operations can be
> optimized too, but not yet
>              cc = str.charAt(0);              // early binding
>              c = ori.length()         // early binding
>         }
>         end = System.currentTimeMillis();
>
>         println "run ${count} times in ${end - start} millis"
>     }
>
>     static void main(args) {
>         new MethCall().func()
>     }
> }
>
> The default late binding produced 1200 ms while partial optimization
> resulted in 500ms. My goal is to reduce the overhead of calling Java
> libraries to 10% of dynamic dispatching.  Calling Groovy methods is
> another issue.
>
> Currently a few testcases in the build are still broken.
>
> I'm using a modified version of MetaClass to attempt early bindings.
> Any
> other ideas that I might have missed?
>

Bing - this looks very good!

I'm not sure that this is currently 100% safe, however.

If the Java class is non final then it is possible for it to be subclassed by a Java class which implements GroovyObject (or by a Groovy class). If the subclass implements invokeMethod then it's not safe to use early binding.

You example is safe because String is final.

I have raised a JIRA issue which proposes that a Groovy class cannot subclass a Groovy class which does not implement invokeMethod and then implement it (the same for get/set Property). It might be a good idea to have a rule saying that a Groovy class can't subclass a Java class which does not implement GoovyObject (other than Object, of course) and then implement invokeMethod or get/set property (i.e. the compiler adds final methods to the Groovy class unless the programmer provides them
explicitly)

In the case of a Java class subclassing a Java class (other than
Object) and implementing GroovyObject there's not much that can be done as far as I can see. I'd be perfectly happy if programmers were that the dynamic calls would not be made if the object was cast to the superclass in Groovy.

Can you see any other way of making this safe?

John Wilson
The Wilson Partnership
http://www.wilson.co.uk



Miles Parker | 1 Jun 2004 17:10
Picon
Favicon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


Great, this is just what I need, as I am calling Java framework code. Any chance 
I could get a copy of your changes to try out?

bing ran wrote:
> Incidentally I have an experimental  implementation of early binding _only
> for_  calling java libs (JDK and third party jars) on my local machine. I'm
> avoiding static dispatching for Groovy classes due to the invokeMethod issue
> (also the behavior of Groovy method call in general). GDK extensions are
> excluded too.  I'm seeing performance improvement in the range of 100-200%
> in my test cases. The mechanism is the same as suggested by you guys: method
> invocations on  variables defined with explicit type info are candidates for
> early bindings if the invocation can be unambiguously mapped to a method of
> the declaring class. 
> 
\
> 

Bill Burdick | 1 Jun 2004 12:15

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?

What about indicating what type of dispatching is required in a Groovy 
object's metaclass (with a flag or a different subclass of Metaclass for 
those classes or metaclasses which override invokeMethod)?  Generated 
code could just check the metaclass to decide whether to call 
invokeMethod.  You can cache the metaclass to eliminate redundant calls 
to getMetaClass().  With some changes to the model, it might even be 
possible to bypass getMetaClass() for subclasses of GroovyObjectSupport 
and use the metaClass field directly.

This type of technique was first used AFAIK in Smalltalk by Alan Borning 
to implement multiple inheritence within a single-inheritence VM.

John Wilson wrote:

> I have raised a JIRA issue which proposes that a Groovy class cannot 
> subclass a Groovy class which does not implement invokeMethod and then 
> implement it (the same for get/set Property). It might be a good idea 
> to have a rule saying that a Groovy class can't subclass a Java class 
> which does not implement GoovyObject (other than Object, of course) 
> and then implement invokeMethod or get/set property (i.e. the compiler 
> adds final methods to the Groovy class unless the programmer provides 
> them explicitly)
>
> In the case of a Java class subclassing a Java class (other than 
> Object) and implementing GroovyObject there's not much that can be 
> done as far as I can see. I'd be perfectly happy if programmers were 
> that the dynamic calls would not be made if the object was cast to the 
> superclass in Groovy.
>
> Can you see any other way of making this safe?

--

-- 
	Bill Burdick
	Bill@...

bing ran | 1 Jun 2004 17:58

RE: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?

Yes, that's the purpose I have in my mind when I optimize the class
generator. For now my focus is on String and number manipulations (but the
code is generic). I'll try to speed up a little more. As Chris has said we
need to play safe here since it involves issues that are not quite clearly
defined in the spec.  I might post it in the Jira database first so we can
test it without contaminating the CVS. 

Keep tuned:)

-----Original Message-----
From: Miles Parker [mailto:milesparker@...] 
Sent: Tuesday, June 01, 2004 11:11 PM
To: dev@...
Subject: Re: [groovy-dev] static dispatch, was [groovy-user] Groovy
Performance 20-90% of Java?

Great, this is just what I need, as I am calling Java framework code. Any
chance I could get a copy of your changes to try out?

bing ran wrote:
> Incidentally I have an experimental  implementation of early binding 
> _only for_  calling java libs (JDK and third party jars) on my local 
> machine. I'm avoiding static dispatching for Groovy classes due to the 
> invokeMethod issue (also the behavior of Groovy method call in 
> general). GDK extensions are excluded too.  I'm seeing performance 
> improvement in the range of 100-200% in my test cases. The mechanism 
> is the same as suggested by you guys: method invocations on  variables 
> defined with explicit type info are candidates for early bindings if 
> the invocation can be unambiguously mapped to a method of the declaring
class.
> 
\
> 

John Wilson | 1 Jun 2004 18:48
Picon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On 1 Jun 2004, at 16:09, bing ran wrote:

> John, your proposal makes sense to me, and identifies a hole in my 
> current code, although we do not necessarily need to bar classes from 
> having methods of the same signature without declaring to 
> implement the GroovyObject interface.- they just get ignored. As a 
> matter of fact, I have yet to find how to define a Groovy class that 
> does NOT implement GroovyObject:)
>
> I'll add checks to my code so that any messages sent to GroovyObject 
> will take late binding - Groovy means dynamic anyway.
>

There is another solution to the problem of a Groovy class subclassing 
a class which does not override the default invokeMethod() method and 
then implementing invokeMethod().

class MyGroovyClass {
	f() {
		println 'hello'
         }
}

class MyGroovySubclass extends MyGroovyClass {
	invokeMethod(String name, Object args) {
		.... do something sneaky
	}
}

The compiler could override all the methods in the superclass (there's 
a problem with final methods, though) and redirect the calls to 
invokeMethod()

class MyGroovySubclass extends MyGroovyClass {
	invokeMethod(String name, Object args) {
		.... do something sneaky
	}

	f() {
		invokeMethod('f', new Object[0])
	}
}

This means that you can always do direct calls and the object will know 
if they are to be made dynamic.

John Wilson
The Wilson Partnership
http://www.wilson.co.uk

Mark C. Chu-Carroll | 1 Jun 2004 19:56
Picon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On Jun 1, 2004, at 12:48 PM, John Wilson wrote:

>
> On 1 Jun 2004, at 16:09, bing ran wrote:
>
>> John, your proposal makes sense to me, and identifies a hole in my 
>> current code, although we do not necessarily need to bar classes from 
>> having methods of the same signature without declaring to 
>> implement the GroovyObject interface.- they just get ignored. As a 
>> matter of fact, I have yet to find how to define a Groovy class that 
>> does NOT implement GroovyObject:)
>>
>> I'll add checks to my code so that any messages sent to GroovyObject 
>> will take late binding - Groovy means dynamic anyway.
>>
>
> There is another solution to the problem of a Groovy class subclassing 
> a class which does not override the default invokeMethod() method and 
> then implementing invokeMethod().
> class MyGroovyClass {
> 	f() {
> 		println 'hello'
>         }
> }
>
> class MyGroovySubclass extends MyGroovyClass {
> 	invokeMethod(String name, Object args) {
> 		.... do something sneaky
> 	}
> }
>
> The compiler could override all the methods in the superclass (there's 
> a problem with final methods, though) and redirect the calls to 
> invokeMethod()
>
>
> class MyGroovySubclass extends MyGroovyClass {
> 	invokeMethod(String name, Object args) {
> 		.... do something sneaky
> 	}
>
> 	f() {
> 		invokeMethod('f', new Object[0])
> 	}
> }

This is pretty much exactly what I'm working on doing for direct 
binding in groovy-498. There is
one catch to this approach, which is that the code for the invokeMethod 
call in the over-rides needs
to be a little more complicated. Unless I'm confused, what will happen 
if you just do "f()" as above
is that calling MyGroovySubclass.f will invoke 
MyGroovySubclass.invokeMethod("f", ...), which
will in turn find and call MyGroovySubclass.f...

So you need to make sure that the generated methods that defer to 
invokeMethod do *not*
wind up just recursing. I'm still reading the code to figure out how to 
get that right.

	-Mark

> This means that you can always do direct calls and the object will 
> know if they are to be made dynamic.
>
> John Wilson
> The Wilson Partnership
> http://www.wilson.co.uk
>
>

Mark Craig Chu-Carroll,  IBM T.J. Watson Research Center
*** The Stellation project: Advanced SCM Research
***      http://stellation.eclipse.org
*** Work: mcc@.../Home: markcc@...

John Wilson | 1 Jun 2004 21:17
Picon

Re: [groovy-dev] static dispatch, was [groovy-user] Groovy Performance 20-90% of Java?


On 1 Jun 2004, at 18:56, Mark C. Chu-Carroll wrote:

> [snip]

>
> This is pretty much exactly what I'm working on doing for direct 
> binding in groovy-498. There is
> one catch to this approach, which is that the code for the 
> invokeMethod call in the over-rides needs
> to be a little more complicated. Unless I'm confused, what will happen 
> if you just do "f()" as above
> is that calling MyGroovySubclass.f will invoke 
> MyGroovySubclass.invokeMethod("f", ...), which
> will in turn find and call MyGroovySubclass.f...
>
> So you need to make sure that the generated methods that defer to 
> invokeMethod do *not*
> wind up just recursing. I'm still reading the code to figure out how 
> to get that right.
>

yes that's certainly a problem!

Would something like this work?

class MyGroovySubclass extends MyGroovyClass {
	invokeMethod(String name, Object args) {
		.... do something sneaky
	}

	f() {
		invokeMethod('$f', new Object[0])
	}

	$f() {
		super.f()
	}
}

On reflection I don't think it would (the super invokeMethod might well 
want to see the name f to do something special).

What about adding another parameter to invokeMethod so that a normal 
call would be invokeMethod('f', new Object[0], this) then in this case 
passing an inner class instance which acted as a facade over the 
directly callable methods? So when the method was called by reflection 
it would be called on the third parameter.

It's a bit of a challenge :)

John Wilson
The Wilson Partnership
http://www.wilson.co.uk


Gmane