Skip to main content

Closure and performance

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

I've read the proposal about
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)
instead of a invokedynamic call,
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 >>