Java8 Stream and how performance evaluation tools recommended

As a technician, learning new knowledge is the basic homework. Some knowledge is had to learn some knowledge is even more powerful after learned, Java8 Stream is both the knowledge of both. Not to learn not read, learn to write code to play even more powerful.

In the chapter on "Java8 Stream Detailed and practical new features," we introduced the basic use of Java8 Stream, try feeling is not so cool? When using only one line of code to get the end result is not never want to use a for loop iteration over and over again to go up.

At the same time, you also see something like "How Java8 Lambda expressions and flow operations to make your code five times slower," such an article, so today will take you through the preparation of test program to check it out, look at the performance in the end of Stream how is it. At the same time, we meet a very good performance testing tool junitperf.

test environment

First synchronization tools and information about the test environment:

  • JDK version: 1.8.0_151.
  • Computer configuration: MacBook Pro i7,16G memory.
  • Java testing tools: junitperf and Junit.
  • IDE:intellij IDEA。

In the process of testing the computer has opened a lot of other applications, but basically did not operate.

Experiment 1: basic type iterative

The basic test program, initialize an int array 500 million random numbers. Then find the minimum of a number from this array.

Test methods using three control units Reference:

  • testIntFor: Test for loop execution time;
  • testIntStream: Stream test serial execution time;
  • testIntParallelStream: Test Stream parallel execution time;

Test procedures relevant code:

public class StreamTest {

    public static int[] arr;

    @BeforeAll
    public static void init() {
        arr = new int[500000000];
        randomInt(arr);
    }

    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntFor() {
        minIntFor(arr);
    }

    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntParallelStream() {
        minIntParallelStream(arr);
    }

    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntStream() {
        minIntStream(arr);
    }

    private int minIntStream(int[] arr) {
        return Arrays.stream(arr).min().getAsInt();
    }

    private int minIntParallelStream(int[] arr) {
        return Arrays.stream(arr).parallel().min().getAsInt();
    }

    private int minIntFor(int[] arr) {
        int min = Integer.MAX_VALUE;
        for (int anArr : arr) {
            if (anArr < min) {
                min = anArr;
            }
        }
        return min;
    }

    private static void randomInt(int[] arr) {
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt();
        }
    }
}

Basic operation flow: random array initialized by the init method @BeforeAll annotated, and then performing the above three unified test method.

On the unit test method has the following comments:

@JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})

Annotations The annotated as junitperf provided, wherein the duration is the duration of the execution of this code, in milliseconds; WarmUp preheat time, preheat one second herein; Reporter output report format, HTML display used here, see the effect can be more intuitive.

Everything good above are ready, the rest is the uniform implementation of unit testing. FIG three execution results are as follows.

image

image

image

For basic types (int) operating results of the analysis:

  • Serial Stream implementation does not as high for the cycle performance, consuming about twice the for loop.
  • Stream parallel execution performance is better than the for loop, consuming about half of the for loop.
  • There are no machines to test different number of cores, but with the increase in the number of parallel Stream server nuclear inevitably faster.

Experiment II: Object Iteration

List to generate a list, the list of randomly generated string of 10000000, and respectively smallest character string is calculated in different ways.

A basic operation is the same experiment, the code is no longer posted directly see the effect of the test of FIG.

image

image

image

For the object (String) operating results of the analysis:

  • Stream of performance for the cycle has little difference, time-consuming probably about 1.25 times the for loop.
  • Stream parallel execution performance is better than the for loop, but higher than the base type of advantage, already consuming less than half of the for loop.
  • For different number of core servers, Stream will also be more high efficiency.

Experiment three: reduction of complex objects

List generate a list, a list of which store 1 million User object. Each object contains a user name and a particular distance movement of the user, the same user may contain multiple records in the List in motion. Now users of statistics in different ways how far a total of exercise.

The basic idea of ​​the same test, just to put the code Stream-based algorithm, so that we understand the complexity reduction target Stream of how to use.

// 串行写法
users.stream().collect(
                Collectors.groupingBy(User::getUserName,
                        Collectors.summingDouble(User::getMeters)));
// 并行写法                     
users.parallelStream().collect(
                Collectors.groupingBy(User::getUserName,
                        Collectors.summingDouble(User::getMeters)));

Let's look at the data of test results:

image

image

image

Complex object reduction operations, the results of the analysis:

  • Stream based on the operation efficiency is significantly higher than the for loop, and the effect is more pronounced parallel.
  • Also, as the number of servers nuclear, efficiency of parallel Stream will be higher.

Finally, it is recommended to look at this with good Java performance testing tool, GitHub address: https: //github.com/houbb/junitperf. There are detailed instructions above. The only thing missing is an example of pre-initialized data, and examples in this article already make up this part of the missing.

summary

By comparing the experimental groups of the above, we can see the following conclusions:

  • For simple operations, such as the type of base traversal, for loop performance is significantly higher than the serial Stream operations. However, as the number of parallel operations Stream core servers increases, it will be better than for loop.
  • For complex operations, serial Stream loop performance is not bad for the vertical, parallel Stream but performance has been the unmatched.
  • Especially for multi-layer filter and a set of reduction operations, in terms of performance to be written or much better than for loop.

One sentence is: simple for loop can be complicated to operate devaluation Stream.

Stream now write simple, good performance, if future JDK optimized for it, it will also enjoy the convenience and performance, why not do it.

Original link " Java8 Stream and how performance evaluation tools recommended "

This article from the blog article multiple platforms OpenWrite release!

Guess you like

Origin www.cnblogs.com/secbro/p/11653574.html