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