201305 - Lambda by R. Forax
Transcript of 201305 - Lambda by R. Forax
![Page 1: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/1.jpg)
Dans les traboulesdes lambdas
Rémi ForaxUPEMMai 2012
![Page 2: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/2.jpg)
2
Moi
MCF à l'Université Paris Est Marne-la-vallée
Joue avec Java depuis trop longtemp pour l'avouer
Créateur de langages dynamiques ou pas
Expert pour les JSR 292 (invokedynamic) et JSR 335 (lambda)
Contributeur OpenJDK, ASM, Tatoo, PHP.reboot, JDart, etc...
![Page 3: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/3.jpg)
3
Un exemple de lambda
enum Gastronomy { rosette, andouillette, coq_au_vin, tripe, cardoon}
private static List<Gastronomy> getGastronomyList() { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); Collections.sort(list, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list;}
public static void main(String[] args) { System.out.println(getGastronomyList());}
![Page 4: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/4.jpg)
4
Exemple un poil plus compliqué
private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2;}
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2;}
![Page 5: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/5.jpg)
5
Parties codantes
private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2;}
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2;}
![Page 6: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/6.jpg)
6
Closure ??
Expression que l'on veut voir comme une valeur
Les closures/lambda existent dans plein d'autres langages
Lisp/Clojure, Ruby, Groovy, Scala, C#, JavaScript/Python, et même C++/Objective C récemment
En Java, on a des classes annonymes
Youpi !Nan, je rigole :)
![Page 7: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/7.jpg)
7
Problème des classes anonymes
Verbeux visuellement
rapport signal/bruit pas terrible
Sémantiquement bizarre
on veut envoyer une expression, créont une classe ...
Perf discutable (pour des closures)
création d'une instance à chaque appel
+ 1 classe sur le disque
+ 1 instance de java.lang.Class et ses métadatas en mémoire
![Page 8: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/8.jpg)
8
Exemple de lambdas(sans lambdas)
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2;}
![Page 9: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/9.jpg)
9
Exemple de lambdas(avec lambdas)
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> { return g1.name().compareTo(g2.name()); }); return list2;}
La syntaxe utilise -> (light arrow) et pas => (fat arrow) comme en Scala ou en C#
![Page 10: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/10.jpg)
10
Inférence de type !
Le compilateur peut calculer le type des paramétres d'une lambda !
la méthode sort() prend une liste de Gastronomydonc elle attends un Comparator<Gastronomy>
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> { return g1.name().compareTo(g2.name()); }); return list2;}
Le compilo n'utilise pas l'expression de la lambda pour faire l'inférence !
![Page 11: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/11.jpg)
11
Exemple de lambdas(avec lambdas + inférence)
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (g1, g2) -> g1.name().compareTo(g2.name()) ); return list2;}
![Page 12: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/12.jpg)
12
Syntaxe: Lambda expression
sans paramètre
() -> System.out.println("Vive l'OL")
avec un paramètre (+ inférence)
employee -> employee.isManager()
avec plusieurs paramètres
en déclarant les types(int x, int y) -> x == y
sans déclarer les types (+ inférence)(x, y) -> x == y
![Page 13: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/13.jpg)
13
Syntaxe: Lambda instruction
sans paramètre
() -> { System.out.println("Vive l'OL");}
avec un paramètre (+ inférence)
employee -> { return employee.isManager();}
avec plusieurs paramètres (+ inférence)
(index1, index2) -> { list.set(index1, list.get(index2));}
![Page 14: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/14.jpg)
14
Sémantique
Typé par une functional interface (ex SAM)
Runnable, Callable, Filter, Function, ...
Une lambda n'est pas un objet
“this” représente la classe courante pas la lambda
Une lambda est convertissable en un objet qui implante une functional interfaceRunnable r = () -> System.out.println("LOL?")
objet pas objet
![Page 15: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/15.jpg)
15
Et les collections ?
Ici on filtre une liste, donc au lieu de
private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2;}
![Page 16: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/16.jpg)
16
Et les collections ?
On aimerait bien écrire
private static List<Gastronomy> prefixList( String prefix, List<Gastronomy> list) { return list.filter(g -> g.name().startsWith(prefix)) .toList()}
Operation lazyOperation pas lazy
Heu, toList() sur une liste, vraiment ??
![Page 17: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/17.jpg)
17
Programmation déclarative
list.filter(...) .map(...) .reduce(...)
on veut éviter les structures de données intermédiaire
lambdas
list filter map reduce
list filter map
reduce
Création (pipeline)
exécution
![Page 18: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/18.jpg)
18
Programmation déclarative
Permet la programmation parallèle
On split les données en amont en on envoie le calcul sur différentes threads
● Disponible pour Java 8
Permet d'utiliser les GPUs
On émet le code PTX/HSAIL correspondant● Projet Sumatra (prototype avec Graal)
With great power there must also come — great responsibility!
L'utilisateur ne doit pas faire d'effet de bord dansles lambdas !!
![Page 19: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/19.jpg)
19
Interface java.util.Stream
Sequentielle ou parallelelist.stream() ou list.parallelStream()
Deux types de methodeintermédiaire
filter, map, sorted, distinct, flatMap ...
terminalesforEach, reduce, collect, findFirst ...
L'implantation n'utilise pas de structures intermédaires mais un pipeline !
Un effet de bord, t'es mort !
![Page 20: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/20.jpg)
20
Sans l'API des streams
private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2;}
![Page 21: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/21.jpg)
21
Avec l'API des streams
private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) {
return list.stream() .filter(g -> g.name().startsWith(prefix)) .collect(Collectors.toList());}
Bonus! pas besoin de déclarer la variable locale final !
![Page 22: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/22.jpg)
22
Le coté sombre
>= JDK8< JDK 8
Où sont passées mes belles interfaces ?
![Page 23: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/23.jpg)
23
Traits
Pour ajouter le support des lambdas au collections
Les méthodes stream() et parallelStream()
Il faut pouvoir ajouter des méthodes à une interface
Il faut mettre du code dans les interfaces
Don't panic
Cela s'appelle des traits(trivia: les traits de Scala ne sont pas des traits)
![Page 24: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/24.jpg)
24
Default methods
Une méthode qui a du code dans une interface doit être taggée default
Une méthode par défaut est utilisée par une classe si il n'y a pas de méthode définie ou fournie par une sous classe
public interface Iterator<T> { public abstract boolean hasNext(); public abstract T next(); public default void remove() { throw new UnsupportedOperationException(); }}
![Page 25: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/25.jpg)
25
Et le problème du diamand
Une interface accepte du code
mais pas de champs
Pas de problème de redéfinition de champ donc
Problème si on implante deux interfaces qui ont chacune une méthode ayant du code– Si une interface hérite de l'autre, on prend la méthode de la
sous-interface
– Sinon, le compilo plante
interface I { default void m() { } }interface J { default void m() { } }class A implements I, J { // compile pas}
![Page 26: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/26.jpg)
26
Super sur des interfaces
La syntaxe, I.super.m() permet d'appeler la méthode m de l'interface I.
donc pour résoudre le conflit
interface I { default void m() { } }interface J { default void m() { } }class A implements I, J { public void m() { I.super.m(); }}
![Page 27: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/27.jpg)
27
Retrofit
Avec Java 8, l'interface java.util.List possède enfin une méthode sort (par défaut)
qui appele Collections.sort :)
private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); list2.sort((g1, g2) -> g1.name().compareTo(g2.name())); return list2;}
![Page 28: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/28.jpg)
28
Avoir une méthode intermédiaire n'est plus nécessaire, on peut tout écrire dans une seule méthode
Et en utilisant Comparators.comparing()
private static List<Gastronomy> getGastronomyList(String prefix) { return Arrays.stream(Gastronomy.values()) .filter(g -> g.name().startsWith(prefix)) .sorted(Comparators.comparing(g -> g.name())) .collect(Collectors.toList());}
public static void main(String[] args) { System.out.println(getGastronomyList("c"));}
Exemple (suite)
![Page 29: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/29.jpg)
29
Method Reference
Il existe une syntaxe spécifique pour les lambdas qui appel juste une méthode
g -> g.name() peut s'écrire Gastronomy::name
On ne spécifie pas le type des paramètres,le compilateur utilise la fonctional interface pour les trouver
Il est aussi possible de capturer une valeur
Callable<String> c = "foo"::toUpperCase()System.out.println(c.call()); // prints FOO
![Page 30: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/30.jpg)
30
Avec des Method References
Et tout dans le main.
public static void main(String[] args) { Arrays.stream(Gastronomy.values()) .filter(g -> g.name().startsWith("c")) .sorted( Comparators.comparing(Gastronomy::name)) .forEach(System.out::println);}
![Page 31: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/31.jpg)
31
Hunder the hoodHunder the hood
![Page 32: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/32.jpg)
32
Compilation - Création
Une référence sur une méthode est crée en utilisant invokedynamic
BiFunction<String, Integer, Character> fun = String::charAt;
est transformé par le compilateur en
code:0: invokedynamic lambda() #0 ()Ljava/util/function/BiFunction;5: astore_1
![Page 33: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/33.jpg)
33
Compilation - Création
constants:#0: #15 invokestatic java/lang/invoke/LambdaMetafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments: #16 invokeinterface java/util/function/BiFunction.apply :(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; #17 invokevirtual java/lang/String.charAt:(I)C #18 (Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Character;
code:0: invokedynamic lambda() #0 ()Ljava/util/function/BiFunction;5: astore_1
Functional interface
Methodede l'interface
Methoderéférencée
Signature générique réifiée
![Page 34: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/34.jpg)
34
Intérêt d'utiliser invokedynamic
La création de l'objet implantant la functional interface n'est pas écrite dans le code généré
Peux changer en fonction des versions du JDK, des optimisations implantées dans la VM
Si l'objet est constant, il peut être ré-utilisé
Pour le jdk8, utilise ASM pour générer une classe proxy dynamiquement
et sans vérification du bytecode
![Page 35: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/35.jpg)
35
Compilation - Appel
L'appel se fait en utilisant la méthode de l'interface
BiFunction<String, Integer, Character> fun = ...char c = fun.apply("foo", 0);
et en bytecode
7: ldc #3 // String “foo” 9: iconst_0 10: invokestatic #4 // Integer.valueOf:(I)Ljava/lang/Integer;13: invokeinterface #5, 3 // BiFunction.apply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;18: checkcast #6 // class Character21: invokevirtual #7 // Character.charValue:()C24: istore_2
![Page 36: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/36.jpg)
36
Et les perfs ? / un nano-test
public class HoodPerf { private static int COUNTER;
private static void test() { BiFunction<String, Integer, Character> fun = String::charAt; char c = fun.apply("foobar", 5); COUNTER += c; // side effect }
public static void main(String[] args) { for(int i=0; i<10_000; i++) { test(); } System.out.println(COUNTER); System.out.println(end – start); }}
Ce code ne marchepas pour faire unbenchmark mais ...
![Page 37: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/37.jpg)
37
pour voir de l'assembleur ...
{0x00007fd655851530} 'test' '()V' in 'HoodPerf'...d64d074300: mov %eax,-0x14000(%rsp)...d64d074307: push %rbp...fd64d074308: sub $0x20,%rsp...d64d07430c: mov $0xef010e68,%r10 ; {oop(a 'HoodPerf$$Lambda$1')}...d64d074316: mov 0x8(%r10),%r8d ; getClass...d64d07431a: mov $0xeeedaf80,%r11 ; {oop(a 'java/lang/Integer'[256] )}...d64d074324: mov 0x210(%r11),%r11d ;*aaload ; - java.lang.Integer::valueOf@21 (line 809)...d64d07432b: cmp $0xc6860240,%r8d ; {metadata('HoodPerf$$Lambda$1')}...d64d074332: jne ...d64d0743e9 ;*invokeinterface apply ; - HoodPerf::test@13 (line 10)...d64d074338: mov 0xc(%r11),%ebp ;*getfield value ; - java.lang.Integer::intValue@1 (line 871) ; implicit exception: dispatches to 0x00007fd64d074486...d64d07433c: test %ebp,%ebp...d64d07433e: jl ...d64d074401 ;*iflt ; - java.lang.String::charAt@1 (line 650)...d64d074344: cmp $0x3,%ebp...d64d074347: jge ...d64d074401 ;*if_icmplt ; - java.lang.String::charAt@10 (line 650)...d64d07434d: cmp $0x3,%ebp...d64d074350: jae ...d64d0743b7
ahah
charAt
![Page 38: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/38.jpg)
38
Pour info, le code de String.charAt
public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIOOBException(index); } return value[index];}
...070d06a53c: test %edx,%edx
...070d06a53e: jl ...070d06a575 ;*iflt ; - java.lang.String::charAt@1 (line 650)...070d06a540: mov 0xc(%rsi),%ebp ;*getfield value ; - java.lang.String::charAt@6 (line 650)...070d06a543: mov 0xc(%rbp),%r10d ;*arraylength ; - java.lang.String::charAt@9 (line 650) ; implicit exception: dispatches to ...070d06a589...070d06a547: cmp %r10d,%edx...070d06a54a: jge ...070d06a575 ;*if_icmplt ; - java.lang.String::charAt@10 (line 650)...070d06a54c: cmp %r10d,%edx...070d06a54f: jae ...070d06a562...070d06a551: movzwl 0x10(%rbp,%rdx,2),%eax
![Page 39: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/39.jpg)
39
et encore de l'assembleur ...
...d64d074352: mov $0xef015e10,%r10 ; {oop([C)}
...d64d07435c: movzwl 0x10(%r10,%rbp,2),%ebp ;*caload ; - java.lang.String::charAt@27 (line 653)...d64d074362: cmp $0x7f,%ebp...d64d074365: jg ...d64d074411 ;*if_icmpgt ; - java.lang.Character::valueOf@3 (line 4570)...d64d07436b: cmp $0x80,%ebp...d64d074371: jae 0x00007fd64d0743c9...d64d074373: mov $0xeef0e828,%r10 ; {oop(a 'java/lang/Character'[128] )}...d64d07437d: mov 0x10(%r10,%rbp,4),%r10d ;*aaload ; - java.lang.Character::valueOf@10 (line 4571)...d64d074382: test %r10d,%r10d...d64d074385: je ...d64d0743d9 ;*invokevirtual charValue...d64d074387: mov $0xeef05ab8,%r11 ; {oop(a 'java/lang/Class' = 'HoodPerf')}...d64d074391: mov 0x58(%r11),%r11d ;*invokestatic valueOf...d64d074395: movzwl 0xc(%r10),%r10d...d64d07439a: add %r10d,%r11d...d64d07439d: mov $0xeef05ab8,%r10 ; {oop(a 'java/lang/Class' = 'HoodPerf')}...d64d0743a7: mov %r11d,0x58(%r10) ;*putstatic COUNTER...d64d0743ab: add $0x20,%rsp...d64d0743af: pop %rbp...d64d0743b0: test %eax,0x9006c4a(%rip) # ...d65607b000 ; {poll_return}...d64d0743b6: retq Ça sert à quoi ??
charAt
![Page 40: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/40.jpg)
40
... en résumé
Une méthode référence (ou une lambda) qui ne fait pas de capture est une constante
L'appel a une lambda peut être dévirtualisé et inliné comme n'importe quel appel
Le code montré est celui générer par le jdk8b88-lambda avec elision du boxing/unboxing desactivé :(
![Page 41: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/41.jpg)
41
What's next ?
Updates du JDK8
lambda constante sans check de classe
lambda non-constante mieux dévirtualisée
Java 9
Value ObjectInteger, Float, etc ne devrait pas avoir d'identité
=> pas sûr que cela marche
Utilisation du/des GPUs dans les Stream parallele
![Page 42: 201305 - Lambda by R. Forax](https://reader031.fdocument.pub/reader031/viewer/2022020123/5586044ad8b42a3d6b8b46d2/html5/thumbnails/42.jpg)
42
Questions ?
JDK8 Feature Freeze jeudi prochain !
les lambdas sont déjà dans le JDK !
https://jdk8.java.net/download.html
Remonter les bugs sur
la mailing list: lambda-devhttp://mail.openjdk.java.net/mailman/listinfo/lambda-dev
ou bugs.sun.com