美文网首页
JAVA 8 forkjoin实际体验

JAVA 8 forkjoin实际体验

作者: echo_adc8 | 来源:发表于2019-04-02 11:25 被阅读0次

    JAVA8 函数编程

    -都说java8 新的函数式编程特别是并行流式编程,但是并行流的性能并不一定就好

            long starttime1=System.currentTimeMillis();
            //cur,bank,eat均为list 
            cul.parallelStream()
                    .forEach(tar->{
                        if(bank.parallelStream().
                                filter(poi->dwithin(poi.getLocation(),tar.getLocation(),500))
                                .collect(Collectors.toList()).size()>5 &&
                        eat.parallelStream().
                                filter(poi->dwithin(poi.getLocation(),tar.getLocation(),500))
                                .collect(Collectors.toList()).size()>5
                                )
                            res.add(tar);
                            }
    
            );
            System.out.println("并行计算耗时:"+String.valueOf(System.currentTimeMillis()-starttime1));
            System.out.println(res.size());
            System.out.println(res.get(0).getName());
            res.clear();
            long starttime=System.currentTimeMillis();
            for(Pois tar:cul){
                List ttmmpp1=new ArrayList();
                List ttmmpp2=new ArrayList();
                for(Pois poi:bank){
                    if(dwithin(poi.getLocation(),tar.getLocation(),500))
                        ttmmpp1.add(poi);
    
                }
                for(Pois poi:eat){
                    if(dwithin(poi.getLocation(),tar.getLocation(),500))
                        ttmmpp2.add(poi);
    
                }
                if(ttmmpp1.size()>5&&ttmmpp2.size()>5)
                  res.add(tar);
            }
            System.out.println("顺序执行耗时:"+String.valueOf(System.currentTimeMillis()-starttime));
            System.out.println(res.size());
            System.out.println(res.get(0).getName());
    
    
    
    private static boolean dwithin(String A,String B,int radius) {
            try {
                Point a = (Point) reader.read("POINT(" + A.replace(",", " ") + ")");
                Point b = (Point) reader.read("POINT(" + B.replace(",", " ") + ")");
                return a.within(b.buffer(radius));
            }catch(Exception e) {
    
            }
            return false;
        }
    

    没有很复杂的深层循环,两层。结果可能让人有些失望。
    将并行流改成顺序流,时间也少了50ms,这真的是让人有点迷啊。


    并行和顺序执行对比测试

    原因分析

    首先我们看看并行流用了多少线程
    System.out.println("ForkJoinPool.getCommonPoolParallelism() : " + ForkJoinPool.getCommonPoolParallelism());
    输出:一个线程。
    咦,这。。。那设置高一点看看。

     System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "" + 8);
     System.out.println("ForkJoinPool.getCommonPoolParallelism() : " + ForkJoinPool.getCommonPoolParallelism());
    
    

    设置无效,参照如下博客修改了一番。
    在run-edit configurations中设置JVM参数
    -Djava.util.concurrent.ForkJoinPool.common.parallelism=64
    其实这样在CPU核心数量达不到的情况下确实提升水平有限。
    ps:https://blog.csdn.net/blueskybluesoul/article/details/82817007
    按照这个教程修改后,再次测试

    修改后如下

    final Long starttime2=System.currentTimeMillis();
            ForkJoinPool myPool = new ForkJoinPool(8);
            myPool.submit(() ->cul.parallelStream()
                    .forEach(tar->{
                                //System.out.println(tar.getName());
                                if(bank.stream().
                                        filter(poi->dwithin(poi.getLocation(),tar.getLocation(),300))
                                        .collect(Collectors.toList()).size()>5 &&
                                        eat.stream().
                                                filter(poi->dwithin(poi.getLocation(),tar.getLocation(),300))
                                                .collect(Collectors.toList()).size()>5
                                        )res.add(tar);
                            }
    
                    )
            ).get();
            myPool.awaitTermination(3, TimeUnit.SECONDS);
            myPool.shutdown();
    

    修改结果

    • 使用forkjoin指定线程数量,尽管CPU数量有限,依然获得提升。

    • 多次测试,平均顺序流耗时约34秒,并行流耗时约16秒。大概提升一倍的效率。

    相关文章

      网友评论

          本文标题:JAVA 8 forkjoin实际体验

          本文链接:https://www.haomeiwen.com/subject/tdbxmqtx.html