# Closure and performance

Posted by forax on August 24, 2006 at 5:09 AM PDT

function types and closures
and i have noticed that the invocation
of a function type will use the newly introduced bytecode invokedynamic (the gilad blog about invokedynamic) and i think i know why !

So let me introduce a small example of closure, the method
transform applies a transformation
on each item of an array and store the result in the same array.

The transformation is specified using a
function type typed CharSequence(CharSequence)
i.e. a function that takes a CharSequence and returns a CharSequence.

``  static CharSequence[] transform(CharSequence(CharSequence) transformation,CharSequence... array) {    for(int i=0;i<array.length;i++) {      array[i]=transformation(array[i]);    }    return array;  }``

The following code applies an identity transformation :

``  CharSequence(CharSequence) identity = (CharSequence seq) {return seq; };  CharSequence[] seqs=transform(identity,"2","3");  System.out.println(Arrays.toString(seqs));``

So why closure can't use a classical call (invokevirtual)
because the proposal defines subtyping rules between closures.

It is possible to use a function type with not exactly the same
type the the one defined. In our example, the declared signature
is CharSequence(CharSequence seq), one can use instead
a closure typed, by example, String(Object).

``  String(Object) bang = (Object o) {return "!"+o; };  CharSequence[] seqs2=transform(bang,"2","3");  System.out.println(Arrays.toString(seqs2));``

So in the method transform, the call to
transformation can call
a function type with a different signature that the one declared,
that's why invokedynamic must be used here.

So why using invokedynamic is important, it's because it can
hurt performance, invoking a method without the same signature
is more complex than a simple call.

In C#, a delegate method call (a roughly equivalent to closure) is more
expensive than a method call.

Note that this is a special case of invokedynamic, there is
only one method that is applicable for a specific closure
so a smart VM can optimise this case.

Related Topics >>