Stream parallel并行流的思考

1.并行流并不一定能提高效率,就和多线程并不能提高线程的效率一样

因为引入并行流会引起额外的开销,就像线程的频繁上下文切换会导致额外的性能开销一样,当数据在多个cpu中的处理时间小于内核之间的传输时间,使用并行流也就没有什么意义了.

这边用代码演示一下

public static long iterativeSum(long n) {
        long result = 0;
        for (long i = 1L; i <=n; i++) {
            result += i;
        }
        return result;
    }
public static long parallelSum(long n){
        return Stream.iterate(1L, i -> i+1)
                .limit(n)
                .parallel()
                .reduce(0L, Long::sum);
    }

第一个是我们经常使用的for循环,第二个是使用LongStream生成long类型的流,并且通过 parallel并行化,我们看看执行结果

package demo13;

import java.util.function.Function;
  
public class PerformanceClass {

    public static long measureSumPerf(Function<Long, Long> adder, long n) {
        long fastest = Long.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            long sum = adder.apply(n);
            System.out.println("Result: "+ sum);
            long duration = (System.nanoTime() - start) / 1_000_000;
            if (duration < fastest) {
                fastest = duration;
            }
        }
        return fastest;
    }

    public static void main(String[] args) {
        System.out.println(measureSumPerf(ParalleStreams::iterativeSum, 10_000_000));//3
        System.out.println(measureSumPerf(ParalleStreams::parallelSum, 10_000_000));//173
//        System.out.println(measureSumPerf(ParalleStreams::sequentialSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::rangedSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::parallelRangedSum, 10_000_000));
//        System.out.println(measureSumPerf(ParalleStreams::sideEffectSum, 10_000_000));
    }

}

上面只是一个测试代码,我们看到for使用了 3毫秒,但是 并行流竟然使用了 173毫秒,所以parallel并不一定能提高效率

2.这边我们可以使用LongStream来直接生成long类型的数据来避免拆装箱

public static long rangedSum(long n) {
        return LongStream.rangeClosed(1, n).reduce(0L, Long::sum);
    }
        System.out.println(measureSumPerf(ParalleStreams::rangedSum, 10_000_000));//4

这边只使用了4毫秒,所以使用合适的数据结构比无脑的使用并行更有用.

什么高并发,大数据,不如算法和数据机构重要.

原文地址:https://www.cnblogs.com/lishuaiqi/p/12075498.html

时间: 2024-11-07 08:14:57

Stream parallel并行流的思考的相关文章

对集合进行并行计算方法选择的建议:stream的并行流,CompletableFuture

对于集合的并行计算,我们是要使用流(stream)还是CompletableFuture? 如果进行的是计算密集型的操作,并且没有I/O,那么推荐Stream接口,因为实现简单,同时效率也是最高的(如果所         有的线程都是计算密集型的,那就没有必要创建比处理器核数更多的线程). 反之,如果你并行的工作单元还涉及等待I/O的操作(包括网络连接等待),那么使用CompletableFuture灵活性更             好,你可以根据Nthreads=Ncpu * Ucpu * (

java8新特性(六):Stream多线程并行数据处理

转:http://blog.csdn.net/sunjin9418/article/details/53143588 将一个顺序执行的流转变成一个并发的流只要调用 parallel()方法 public static long parallelSum(long n){    return Stream.iterate(1L, i -> i +1).limit(n).parallel().reduce(0L,Long::sum); } 并行流就是一个把内容分成多个数据块,并用不不同的线程分别处理每

java8新特性——并行流与顺序流

在我们开发过程中,我们都知道想要提高程序效率,我们可以启用多线程去并行处理,而java8中对数据处理也提供了它得并行方法,今天就来简单学习一下java8中得并行流与顺序流. 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. Java8中将并行流进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性地通过parallel()与scqucntial()在并行流与顺序流之间进行切换. 一.Fork-Join框架 Fork-Join框架:是java7提供

【Java8实战】使用并行流

除了顺序流外,Java 8中也可以对集合对象调用parallelStream方法或者对顺序流调用parallel方法来生成并行流.并行流就是一个把内容分成多个数据块,并用不同的线程分别处理每个数据块的流.这样在使用流处理数据规模较大的集合对象时可以充分的利用多核CPU来提高处理效率.不过在一些情况下,并行流未必会比顺序流快,甚至会慢很多,所以了解如何高效的使用并行流也至关重要.此外,我们也可以调用流的sequential方法,将并行流转换为顺序流. 测试并行流的性能 举个例子,对1到1000的整

Java8新特性 - 并行流与串行流

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性地通过parallel()和sequential()在并行流和顺序流之间进行切换. 在了解并行流之前,我们首先需要了解Fork/Join框架 Fork/Join框架 Fork/Join框架:在必要的情况下,将一个大任务进行拆分(fork)成若干个小任务(拆到不可在拆时),在将一个个的小任务运算的结果进行汇总(join). Fo

并行流处理数据

一个接受数字n作为参数,并返回从1到n的所有数字之和. public static int intSum(int n) { return Stream.iterate(1, i -> i + 1) .limit(n) .reduce(0, Integer::sum); } 这是一个简单的顺序流,如果n极大,那么显然单线程是有问题的,所以引入了并行概念. public static int parallelIntSum(int n) { return Stream.iterate(1, i ->

在使用Java8并行流时的问题分析

最近在使用Java8的并行流时遇到了坑,线上排查问题时花了较多时间,分享出来与大家一起学习与自查 // 此处为坑 List<Java8Demo> copy = Lists.newArrayList(); numbers.parallelStream().forEach(item -> { copy.add(new Java8Demo(item)); }); 上图用到了parallelStrem并行流,在循环内部往共享变量copy内写值,由于ArrayList本身不具备线程安全性,导致得到

RecursiveTask和RecursiveAction的使用 以及java 8 并行流和顺序流(转)

什么是Fork/Join框架        Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果.比如计算1+2+..+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和,最终汇总这10个子任

for循环、并行流、串行流效率比较

User类 import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor; @Builder@Data@AllArgsConstructor@NoArgsConstructorpublic class User { int id; String name; int sex; int age; } 测试类 import org.springframe