Un article qui compare l'exécution séquentielle vs parallèle des Stream de Java.
En substance :
- Les streams parallèles consomment plus de mémoire.
- Elles deviennent rentables à partir de 1 000 000 d'éléments à traiter
- Sur le PC du mec qui a fait le benchmark, et sans cette info, et avec du recule, son benchmark ne vaut plus grand chose. Par exemple, la parallélisation sur 4 et sur 64 CPU n'aura pas les mêmes effets... Potentiellement, c'est rentable à partir de 125 K éléments, voire moins.
Je suis bluffée ! Les filters des Stream sont toujours plus lents que les boucles classiques en Java.
Le seul moment où les boucles classiques ne sont pas les plus rapides, c'est dans le cas de figure où la taille des collections dépasse les 500 K éléments et que les Parallel Stream sont utilisées à la place des Stream (et que nous sommes sur une architecture multi-cœurs évidemment) ; sinon les Stream perdent à chaque fois.
Je me souviens il y a presque trois ans déjà, avoir passé une soirée avec Chlouchloutte à essayer de comprendre comment marchait la lazy evaluation des streams en Kotlin.
Cet article nous aurait bien aidé.
Si vous utilisiez le plugin gulp-webpack
il vaut mieux passer à webpack-stream
qui est son remplaçant. Pour l'instant, j'utilise Webpack à travers Gulp à la main, mais si webpack-stream
est efficace et réduit la quantité de code des mes tâches Gulp, alors je migrerai.
Je vais faire ma reloue, mais je vous assure qu'écrire du code pour builder du code est une hérésie. Dommage qu'il n'y ait pas de plugin Aurelia pour Brunch.
Toujours sur les tutos en Java 8 je vais essayer de vous expliquer les mapper et la méthode .map de l'API Stream.
Définition 'Mapper' :
Objet ou fonction permettant de convertir un élément en un autre élément.
Exemple :
J'ai une liste de String :
List<String> list = ...;
Que je souhaite convertir en ceci :
List<Integer> sizes; // qui contient la taille de chacune des String de la liste précédente.
En vieux Java j'écrirais :
private List<Integer> convert(List<String> strList) {
List<Integer> result = new ArrayList<>(list.size());
for (String str : strList) {
result.add(str.size());
}
return result;
}
En lambda j'écrirai :
private List<Integer> convert(List<String> strList) {
return strList.stream().map(str -> str.size()).toList();
}
Et votre mapper c'est cette petite lamdba 'str -> str.size()' qui sera appliquée à chaque élément de la liste un par un.
Je poursuis ma migration vers le fonctionnel sur Java 8 avec un petit tuto sur les stream et les map-reduce. Le tout est guidé par une multitude de petits exemples simples.
Un truc d'Amine sur Java 8 :
Stream.of(args).collect(Collectors.joining(SEPARATOR)).toString();