繁体   English   中英

Java并行流性能

[英]Java parallel stream performance

在玩弄新的Java流时,我注意到与并行流的性能有关的一些奇怪现象。 我使用了一个简单的程序,该程序从文本文件中读取单词并计算长度大于5的单词(测试文件包含30000个单词):

    String contents = new String(Files.readAllBytes(Paths.get("text.txt")));
    List<String> words = Arrays.asList(contents.split("[\\P{L}]+"));
    long startTime;
    for (int i = 0; i < 100; i++) {
        startTime = System.nanoTime();
        words.parallelStream().filter(w -> w.length() > 5).count();
        System.out.println("Time elapsed [PAR]: " + (System.nanoTime() - startTime));
        startTime = System.nanoTime();
        words.stream().filter(w -> w.length() > 5).count();
        System.out.println("Time elapsed [SEQ]: " + (System.nanoTime() - startTime));
        System.out.println("------------------");
    }

这将在我的机器上生成以下输出(我仅提及前5个循环和最后5个循环迭代):

Time elapsed [PAR]: 114185196
Time elapsed [SEQ]: 3222664
------------------
Time elapsed [PAR]: 569611
Time elapsed [SEQ]: 797113
------------------
Time elapsed [PAR]: 678231
Time elapsed [SEQ]: 414807
------------------
Time elapsed [PAR]: 755633
Time elapsed [SEQ]: 679085
------------------
Time elapsed [PAR]: 755633
Time elapsed [SEQ]: 393425
------------------
...
Time elapsed [PAR]: 90232
Time elapsed [SEQ]: 163785
------------------
Time elapsed [PAR]: 80396
Time elapsed [SEQ]: 154805
------------------
Time elapsed [PAR]: 83817
Time elapsed [SEQ]: 154377
------------------
Time elapsed [PAR]: 81679
Time elapsed [SEQ]: 186449
------------------
Time elapsed [PAR]: 68849
Time elapsed [SEQ]: 154804
------------------

为什么第一个处理比其他处理慢100倍? 为什么并行流在第一次迭代中比顺序流慢,但在最后一次迭代中却快两倍? 为什么顺序流和并行流都随着时间的流逝变得更快? 这和循环优化有关吗?

以后的编辑:在Luigi的建议下,我使用JUnitBenchmarks实现了基准测试:

List<String> words = null;

@Before
public void setup() {
    try {
        String contents = new String(Files.readAllBytes(Paths.get("text.txt")));
        words = Arrays.asList(contents.split("[\\P{L}]+"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@BenchmarkOptions(benchmarkRounds = 100)
@Test
public void parallelTest() {
    words.parallelStream().filter(w -> w.length() > 5).count();
}

@BenchmarkOptions(benchmarkRounds = 100)
@Test
public void sequentialTest() {
    words.stream().filter(w -> w.length() > 5).count();
}

我还将测试文件中的单词数提高到300000。新结果是:

Benchmark.sequentialTest:[每105轮测得100次,线程:1(顺序)]

取整:0.08 [+-0.04],取整块:0.00 [+-0.00],取整gc:0.00 [+-0.00],GC。调用:62,GC。时间:1.53,时间总计:8.65,时间。暖身:0.81,时间。板凳:7.85

Benchmark.parallelTest:[在105个回合中测出100个,线程:1(顺序)]

取整:0.06 [+-0.02],取整块:0.00 [+-0.00],取整gc:0.00 [+-0.00],GC。调用:32,GC。时间:0.79,时间总计:6.82,时间热身:0.39,时间。台:6.43

因此,最初的结果似乎是由错误的微基准配置引起的...

Hotspot JVM开始以解释模式执行程序,并在进行一些分析后将常用部分编译为本机代码。 因此,循环的初始迭代通常很慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM