import java.util.function.Function;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class ParalleStreamDemo {
public static long parallelSum(long n) {
return Stream.iterate(1L, i -> i+1)
.limit(n)
.parallel()
.reduce(0L, Long::sum);
}
public static long sequenceSum(long n) {
return Stream.iterate(1L, i -> i+1)
.limit(n)
.reduce(0L, Long::sum);
}
public static long iterativeSum(long n) {
long result = 0;
for(int i = 0; i < n; i++) {
result =+ i;
}
return result;
}
public static long parallelSum2(long n) {
return LongStream.rangeClosed(0, n).parallel().reduce(0, Long::sum);
}
public static long sequenceSum2(long n) {
return LongStream.rangeClosed(0, n).reduce(0, Long::sum);
}
public static long test(Function<Long, Long> computer, long n) {
long fastest = Long.MAX_VALUE;
for(int i = 0; i < 100; i++) {
long start = System.currentTimeMillis();
computer.apply(n);
long cost = System.currentTimeMillis() - start;
if( cost < fastest) {
fastest = cost;
}
}
return fastest;
}
public static void run1(long n) {
System.out.println("顺行流"+test(ParalleStreamDemo::sequenceSum, n));
System.out.println("并行流"+test(ParalleStreamDemo::parallelSum, n));
System.out.println("迭代"+test(ParalleStreamDemo::iterativeSum, n));
}
public static void run2(long n) {
System.out.println("顺行流2"+test(ParalleStreamDemo::sequenceSum2, n));
System.out.println("并行流2"+test(ParalleStreamDemo::parallelSum2, n));
System.out.println("迭代2"+test(ParalleStreamDemo::iterativeSum, n));
}
public static void main(String[] args) {
long n = 20_000_000;
run1(n);
run2(n);
}
}
run1执行结果:
顺行流174
并行流628
迭代13
分析:
1.iterate很难分成独立的小块,它每一次调用函数都依赖上一次的结果,整个数字列表最初计算的时候还没准1备好。它使用的是链表,而非数组。
2.java8在java7的分支合并框架的基础上打造。
3.iterate方法它生成的东西是装箱对象Long,需要再拆箱。
正确使用并行流:
顺行流29
并行流24
迭代213
并行过程本身需要对每个过程做地域划分,把每个子流的归纳操作分配给不同的线程,然后合并成一个值,这些jdk背后做的。再多个内核直接移动数据的代价是比较大的。所以我们要保证再一个内核中执行的时间要大于内核间传递数据的时间。