这个问题源自another question的答案,其中建议使用map和reduce来同时计算总和。
在那个问题中有一个complexCalculation(e)
,但现在我想知道如何通过将计算分成两部分来进行更多的并行化,以便complexCalculation(e)
= part1(e)
* {{1 }}。我想知道是否有可能同时计算集合上的part1和part2(再次使用part2(e)
)然后压缩两个结果流,以便两个流的第i个元素与函数*组合,以便得到stream等于可以通过在该集合上映射map()
获得的流。在代码中,这看起来像:
complexCalculation(e)
所以我的问题是:是否存在一些功能,比如我试图在这里描述的Stream map1 = bigCollection.parallelStream().map(e -> part1(e));
Stream map2 = bigCollection.parallelStream().map(e -> part2(e));
// preferably map1 and map2 are computed concurrently...
Stream result = map1.zip(map2, (e1, e2) -> e1 * e2);
result.equals(bigCollection.map(e -> complexCalculation(e))); //should be true
函数?
答案 0 :(得分:4)
parallelStream()保证在提交的顺序中完成。这意味着您不能假设两个parallelStream可以像这样压缩在一起。
您的原始bigCollection.map(e -> complexCalculation(e))
可能会更快,除非您的收藏实际上小于您拥有的CPU数量。
答案 1 :(得分:2)
如果你真的想并行化part2
和part1
(例如你的bigCollection只有很少的元素,少于CPU内核),你可以做以下技巧。假设您在当前类中有两个方法part2
和public long part1(Type t) { ... }
public long part2(Type t) { ... }
:
bigCollection.parallelStream()
.map(e -> Stream.<ToLongFunction<Type>>of(this::part1, this::part2)
.parallel()
.mapToLong(fn -> fn.applyAsLong(e)).reduce(1, (a, b) -> a*b))
.// continue the outer stream operations
创建一个由这些方法创建的两个函数的流,并按照以下方式并行处理:
part1
然而,这是非常罕见的情况。正如@PeterLawrey指出,如果您的外部集合足够大,则无需并行化part2
和[[GNTextFieldsCollectionManager alloc] initWithView:self.view];
。相反,您将并行处理单独的元素。