作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想计算 a^b ,例如2^30,
public long pow(final int a, final int b)
首先我用的是这种方式
return LongStream.range(0, b).reduce(1, (acc, x) -> a * acc); // 1073741824
得到正确的结果。那我要并行计算,自然就改成了
return LongStream.range(0, b).parallel().reduce(1, (acc, x) -> a * acc); // 32
但在这种情况下,结果只是 32
。为什么?
所以为了支持并行我又改了一遍
return Collections.nCopies(b,a).parallelStream().reduce(1, (acc, x) -> acc * x); // 1073741824
在这种情况下它有效。
那么并行
方式有什么问题呢?
最佳答案
reduce要求提供的函数是 associative .您的函数 (acc, x) -> a * acc
不满足要求,因此违反了契约(Contract)。
要关联,函数必须满足 (x op y) op z == x op (y op z)
对于任何 x、y 和 z。但是对于您的函数,(x op y) op z = x*a^2
而 x op (y op z) = x * a
。
此外,提供给 reduce 的第一个参数必须是累加器函数的标识。所以对于任何 x,1 op x == x
一定是真的。但这也不适用于您的累加器函数,因为 1 op x == a
。
正确的做法是:
LongStream.range(0, b).map(x -> a).reduce(1, (u, v) -> u * v);
无论流是并行的还是顺序的,这都能保证正常工作。
关于java - 当计算 a^b 时,为什么 parallel 不起作用但 parallelStream 可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44013553/
我是一名优秀的程序员,十分优秀!