Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java 8 invoke dynamic advantage

Tags:

java

lambda

I am trying to check what invoke dynamic is used http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html

 public class HelloWorld {

     public static void main(String[] args) {

        GreetingLambda lamda=()->System.out.println("Hello");
        lamda.greet();
        GreetingLambda lamda2=()->System.out.println("Hello");
        lamda2.greet();
      }

    }

  interface GreetingLambda{ 
       void greet();    
   }

Bytecode for the same

public class HelloWorld {

/* compiled from HelloWorld.java */

/* inner class */
/* public final static Lookup */

public HelloWorld() {
    /* L2 */
    0 aload_0;                /* this */
    1 invokespecial 8;        /* java.lang.Object() */
    4 return;
}

void print(GreetingLambda arg0) {
    /* L5 */
    0 aload_1;                /* l */
    1 invokeinterface 16 1;   /* void greet() */
    /* L6 */
    6 return;
}

public static void main(java.lang.String[] args) {
    /* L10 */
    0 invokedynamic 27;       /* GreetingLambda greet() */
    3 nop;
    4 nop;
    5 astore_1;               /* lamda */
    /* L11 */
    6 aload_1;                /* lamda */
    7 invokeinterface 16 1;   /* void greet() */
    /* L12 */
    12 invokedynamic 28;      /* GreetingLambda greet() */
    15 nop;
    16 nop;
    17 astore_2;              /* lamda2 */
    /* L13 */
    18 aload_2;               /* lamda2 */
    19 invokeinterface 16 1;  /* void greet() */
    /* L17 */
    24 return;
}

private static void lambda$0() {
    /* L10 */
    0 getstatic 34;           /* java.lang.System.out */
    3 ldc 40;                 /* "Hello" */
    5 invokevirtual 42;       /* void println(java.lang.String arg0) */
    8 return;
}

private static void lambda$1() {
    /* L12 */
    0 getstatic 34;           /* java.lang.System.out */
    3 ldc 40;                 /* "Hello" */
    5 invokevirtual 42;       /* void println(java.lang.String arg0) */
    8 return;
   }
 }

The call to lambda expression is getting replaced with invokedynamic .But I am unable to understand what is the advantage of using such approach .

  1. How is invokedynamic useful or better than anonymousclass generation.
  2. how is it different from invokeinterface which gets generated from below code as it is also doing runtime check.

                       List<String> a = new ArrayList<String>() ;
    
like image 300
coder25 Avatar asked Jan 09 '17 13:01

coder25


2 Answers

For the first question:

Simply spoken: invokedynamic was very carefully designed (thus it took so long to get it into Java); and one of the side effects of that: is extremely efficient performance wise.

See here for some further reading. Quoting from there:

invokedynamic also benefits dynamic language implementers by supporting dynamically changing call site targets -- a call site, more specifically, a dynamic call site is an invokedynamic instruction. Furthermore, because the JVM internally supports invokedynamic, this instruction can be better optimized by the JIT compiler.

So, long story short: at least theoretically, when you can write code that uses invokedynamic instead of some "old school" way of solving the same problem, new invokedynamic solution has a certain chance of being "faster". As in: it is faster to use invokedynamic compared to the old-school way of creating an anonymous inner class and use that.

like image 116
GhostCat Avatar answered Oct 27 '22 01:10

GhostCat


The same blog you are citing has many more articles on jruby optimization. For example here, Charles Nutter is discussing the advantages of invokedynamic.

Briefly put, it's an optimization that allows the jvm to cache and optimize what would otherwise be a mess of method handle lookups and indirection. An additional advantage is that the resulting code is more friendly for the hotspot optimizer, which means that a lot of the optimizations that work with java bytecode now also work for jruby and other jvm languages that use invokedynamic.

The feature was added specifically to the jvm to support dynamic languages where the exact code to bind method handles to is not known until runtime (unlike with static languages).

like image 25
Jilles van Gurp Avatar answered Oct 26 '22 23:10

Jilles van Gurp