groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: JDK8 Streams / Closure cast to interface
Date Tue, 22 Nov 2016 17:00:54 GMT


On 22.11.2016 15:14, Winnebeck, Jason wrote:
> I love Groovy. I also love the new streams functionality in JDK 8. But,
> I am weary of the performance implications of Groovy + Streams, because
> to use streams you must use Groovy closures. I see the code generated
> creates a new closure instance then uses castToType to cast the closure
> to the JDK8 functionality interface. Does Groovy make this efficient, or
> is the proxy generation from this going to be excessive if running a lot
> of small stream operations?

it is using a dynamic proxy with some optimized code paths.. such a 
proxy does for example not have to go through call to get to doCall. If 
you want this really efficient, you have to skip the generation of the 
Groovy Closure instance. This is doable and I plan to do this, but it 
will be a breaking change (all open blocks would be realized using the 
same class for example, having that instance would even become optional).

> I think an interesting feature of Groovy would be if it sees a closure
> cast implicitly or explicitly to a certain interface type, it could make
> the closure implement the interface.  You’d still have the overhead of
> compile-time class generation versus lambdas, but at least you wouldn’t
> have to create proxies, and maybe there is an improved chance of JIT
> inlining? Even if it was supported within a single statement, like
> “Function<String, String> x = {it.trim()}” or Stream.of(“abc”).map {
> it.trim() }, the closure with trim could implement Function. Of course
> for backwards compatibility the class could still extend Closure and
> still implement call methods, but also implement the method apply, which
> delegates to call.

The price question is now... is that going to be cheaper? runtime class 
generation is much more expensive than a reflective call - and 
considering Android, also much more problematic. And you have to be 
aware of the following... If I make a method call with an open block to 
a method taking a functional interface, the point in time for the 
conversion is after runtime method selection and before the actual 
invocation (or during invocation). At this point the original Closure 
instance already exists. Really, without test it is difficult to tell 
about the gain here

Real gains you get only with a much deeper integration

bye Jochen

Mime
View raw message