Le 13 févr. 2011 à 20:38, Rémi Forax a écrit : > On 02/13/2011 07:00 PM, fo...@x9c.fr wrote: >> Le 13 févr. 2011 à 12:55, Rémi Forax a écrit :
(...) >> is there a reasonable estimate of the different >> speeds (supposing that the target would indeed be constant). I mean, is >> the gap as huge as between reflection and handles? >> > > No, the gap is not as huge. Theorically, if the method handle is stored > in a static final field, the difference is just a pointer check. (...) >>> Anyway, as you see you should choose to use one mechanism or the other >>> depending >>> on the use case and not on some benchmark. >>> >> Well, I do not fully understand your point. To some extend, it appears to me >> that both mechanisms can be used to achieve the very same effect. That's >> why I thought the "director's cut" should be performances. >> > > if you know the method handle at link time, you should use invokedynamic, > if you don't know you should use MH.invokeExact. Very valuable information, and rule of thumb -- thanks. (...) > From performance point of view is better to have unrelated final classes > instead of a hierarchy. double, closure etc. can be represented as > Double, MethodHandle (or a class that wraps MethodHandle) etc > and use Object as common super type. My explanation was coarse-grained; there is a 'Value' parent, and then almost all other classes are final children of 'Value'. I acknowledge a little penalty over your suggestion, but my motto could be "safety first". I do not want anyone to pass a child of 'Object' that cannot be handled as a proper language value. >> There again, I wonder if the best is to do a >> "Method.invokeExact(-)" or to play with the "invokedynamic" instruction. >> The former has been implemented easily and is indeed quite fast. >> Is it a good investment to move to le latter, given that it will >> probably entail compile-time generation of one class per target in >> my case ? >> > > Having one class per target is not a requirement at all. > invokedynamic is just a way to install a method handle at a callsite. > Let's take examples (sorry my Caml is a little rusty): Rusty or not (an as far as I can tell it is not), it is always a pleasure to encounter someone talking Caml outside of the caml-list... > # > let rec fib n = > if n < 1 then 1 else fib(n-1) + fib(n-2);; > > > here fib(n-1) and fib(n-2) should be encoded using invokedynamic. Why? they are currently (and happily) encoded using an "invokestatic" instruction (every Caml function being encoded as a "static" method), given that the function to be called is known at compile time. > # p#get_x;; > > p#get_x is also an invokedynamic. This one is a tricky one... For non-camlists "obj#meth" is the syntax for calling the method "meth" over the object "obj". This is tricky because Java and Caml objects are *really* different (e. g. nominal vs structural typing) and to be compatible with the original Caml implementation, I have constraints over the way to encode an object instance. To put it short, it entails having a table for method dispatch, that maps method identifiers to closures. > # let f = (function x -> 1);; > > here f should be a MethodHandle so > > # f 1;; > is a call to MethodHandle.invokeExact() Well, there again, the call to "f" is static as known at compile-time. But if "f" was actually a parameter to an higher-order function, an handle for "f" would have been retrieved from the static method corresponding to the function, and called through "invokeExact" from the higher-order function. Kind regards, Xavier _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev