[JAVA] I was wondering if Stream / ParallelStream / For would use multiple cores, so I looked it up.

Will For Loop use multiple cores? What about Stream / ParallelStream? I compared it with the simple one that I was curious about.

For the behavior of Stream and Parallel Stream, see the JavaOne 2013 Java 8 Streams: Lambda in Top Gear slide.

For the time being, each measurement is performed after performing it a few times.

For loop

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");
    }
}

The time required is 42801ms

for.png

It seems that all 4 cores are used. However, the CPU usage per core does not reach 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");
    }
}

The time required is 41039ms

stream.png

Almost the same as For Loop. I feel that the load is light on the whole.

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");
    }
}

Time required is 1937ms

parallelStream.png

It ends as soon as all cores reach 100% for a moment. About 20 times faster. By the way, if the number of elements is reduced, the difference becomes smaller, so it seems that the larger the number of elements, the larger the difference.

Summary

(In places where ~~ can be used ~~ In places where the number of elements to be processed increases) ParallelStream should be actively considered.

Regarding ~~ For / Stream, although the processing is distributed to multiple cores, it seems that CPU wait is occurring in the synchronous processing to guarantee the order. Therefore, the usage rate per core does not reach 100%, and the processing time is long. ~~

~~ By that amount, it seems that the CPU is always running and the usage rate has risen to 100% because there is no waiting due to synchronization in ParallelStream. ~~

It was unexpected that ~~ For used multiple cores, but other than that, it behaved as expected, so I was convinced in various ways. ~~

~~ By the way, in this test, the processing order was not disturbed even in ParallelStream, but I think that the order was maintained by chance because the processing time in the loop was constant. On the contrary, even with For / Stream, I think that it was almost always possible to go to the next process at the time of synchronization check (there was no waiting judgment), but the fact that there is still such a speed difference means that the overhead of order guarantee is considerable. Is it big? ~~

The order of processing, or the order of output results, was not directly related to the difference between Stream and ParallelStream. So, the speed difference was a pure amount of calculation. I was completely misunderstood about Parallel Stream ... See Java 8 Streams: Lambda in Top Gear around 45:15. Thanks for pointing out the comments.

Recommended Posts

I was wondering if Stream / ParallelStream / For would use multiple cores, so I looked it up.
I didn't know what to write in Maven's scope so I looked it up