[JAVA] Je me demandais si Stream / ParallelStream / For utiliserait plusieurs cœurs, alors je l'ai recherché.

For Loop utilisera-t-il plusieurs cœurs? Qu'en est-il de Stream / ParallelStream? Je l'ai comparé avec le simple qui m'intéressait.

Pour le comportement de Stream et Parallel Stream, voir la diapositive Java 8 Streams: Lambda in Top Gear de JavaOne 2013.

Pour le moment, chaque mesure est effectuée après l'avoir effectuée plusieurs fois.

Pour boucle

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        String str = "";
        for (String val : list) {
            str += val;
        }
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Le temps requis est de 42801ms

for.png

Il semble que les 4 cœurs soient utilisés. Cependant, le taux d'utilisation du processeur par cœur n'atteint pas 100%.

Stream

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        Optional<String> str = list.stream().reduce((val1, val2) -> val1 + val2);
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Le temps requis est de 41039ms

stream.png

Presque le même que For Loop. J'ai l'impression que la charge est légère dans l'ensemble.

ParallelStream

public class StreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 1; i <= 200000; i++) {
            list.add(String.valueOf(i));
        }

        long start = System.currentTimeMillis();

        Optional<String> str = list.parallelStream().reduce((val1, val2) -> val1 + val2);
        System.out.println(str);

        long end = System.currentTimeMillis();
        System.out.println((end - start)  + "ms");
    }
}

Le temps requis est de 1937ms

parallelStream.png

Il se termine dès que tous les cœurs atteignent 100% pendant un moment. Environ 20 fois plus rapide. À propos, si le nombre d'éléments est réduit, la différence devient plus petite, il semble donc que plus le nombre d'éléments est grand, plus la différence est grande.

Résumé

(Dans les endroits où ~~ peut être utilisé ~~ Dans les endroits où le nombre d'éléments à traiter est grand) ParallelStream doit être activement envisagé.

Concernant ~~ For / Stream, bien que le traitement soit distribué sur plusieurs cœurs, il semble qu'une attente CPU se produise dans le traitement synchrone pour garantir l'ordre. Par conséquent, le taux d'utilisation par cœur n'atteint pas 100% et le temps de traitement est long. ~~

~~ De ce montant, Parallel Stream n'a pas à attendre la synchronisation, donc le CPU est toujours en marche et le taux d'utilisation semble avoir augmenté à 100%. ~~

Il était inattendu que ~~ Pour utilisé plusieurs cœurs, mais à part cela, le comportement était comme prévu, donc j'ai été convaincu de différentes manières. ~~

~~ Au fait, dans ce test, l'ordre de traitement n'a pas été perturbé même dans ParallelStream, mais je pense que l'ordre a été maintenu par hasard car le temps de traitement dans la boucle était constant. Au contraire, même avec For / Stream, je pense qu'il était presque toujours possible de passer au processus suivant au moment du contrôle de synchronisation (il n'y avait pas de jugement en attente), mais même ainsi, le fait qu'il y ait une telle différence de vitesse signifie que la surcharge de garantie de commande est considérable. Est-ce gros? ~~

L'ordre de traitement, ou l'ordre des résultats de sortie, n'était pas directement lié à la différence entre Stream et ParallelStream. Donc, la différence de vitesse était un pur calcul. J'étais complètement incompris à propos de Parallel Stream ... Voir Java 8 Streams: Lambda in Top Gear vers 45:15. Merci d'avoir signalé les commentaires.

Recommended Posts

Je me demandais si Stream / ParallelStream / For utiliserait plusieurs cœurs, alors je l'ai recherché.
Je ne savais pas quoi écrire dans la portée de Maven, alors j'ai cherché.