我正在用 Java 中的并行流进行试验,为此我有以下代码用于计算之前的素数n。基本上我有两种方法calNumberOfPrimes(long n)- 4 种不同的变体isPrime(long n)- 2 种不同的变体实际上,我对上述每种方法都有 2 个不同的变体,一个使用并行流的变体,另一个不使用并行流的变体。 // itself uses parallel stream and calls parallel variant isPrime private static long calNumberOfPrimesPP(long n) { return LongStream .rangeClosed(2, n) .parallel() .filter(i -> isPrimeParallel(i)) .count(); } // itself uses parallel stream and calls non-parallel variant isPrime private static long calNumberOfPrimesPNP(long n) { return LongStream .rangeClosed(2, n) .parallel() .filter(i -> isPrimeNonParallel(i)) .count(); } // itself uses non-parallel stream and calls parallel variant isPrime private static long calNumberOfPrimesNPP(long n) { return LongStream .rangeClosed(2, n) .filter(i -> isPrimeParallel(i)) .count(); } // itself uses non-parallel stream and calls non-parallel variant isPrime private static long calNumberOfPrimesNPNP(long n) { return LongStream .rangeClosed(2, n) .filter(i -> isPrimeNonParallel(i)) .count(); } // uses parallel stream private static boolean isPrimeParallel(long n) { return LongStream .rangeClosed(2, (long) Math.sqrt(n)) .parallel() .noneMatch(i -> n % i == 0); } // uses non-parallel stream private static boolean isPrimeNonParallel(long n) { return LongStream .rangeClosed(2, (long) Math.sqrt(n)) .noneMatch(i -> n % i == 0); }我试图找出,和中的哪一个在正确使用并行流的效率方面是最好calNumberOfPrimesPP的calNumberOfPrimesPNP,以及为什么它是最好的。calNumberOfPrimesNPPcalNumberOfPrimesNPNPPS:我知道这不是计算素数的最佳方法。 埃拉托色尼筛法和其他更复杂的方法可以做到这一点。但是通过这个例子,我只想了解并行流的行为以及何时使用它们。
1 回答
海绵宝宝撒
TA贡献1809条经验 获得超8个赞
我认为,很明显,为什么 NPP 如此缓慢。
将结果数字排列在表格中:
| _P | _NP
-------+----------+---------
P_ | 2364 | 265
-------+----------+---------
NP_ | 11424 | 1138
-------+----------+---------
所以你看到当外部流是并行的时候它总是更快。这是因为流中有很多工作要做。因此,与要完成的工作相比,处理并行流的额外开销很低。
您还看到,当内部流不并行时,它总是更快。isPrimeNonParallel比 快isPrimeParallel。这是因为流中没有太多工作要做。在大多数情况下,经过几步之后就可以清楚地知道该数字不是素数。一半的数字是偶数(只有一步)。与要完成的工作相比,处理并行流的额外开销很高。
添加回答
举报
0/150
提交
取消