3

我发现了一个类似的问题,但它似乎有一个更简单的情况,其中昂贵的操作总是相同的。就我而言,我想收集一组我想并行执行的昂贵 API 调用的结果。

说我有:

def apiRequest1(q: Query): Option[Result]
def apiRequest2(q: Query): Option[Result]

哪里q是相同的值。

我想要一个List[Result]或类似的(显然List[Option[Result]]很好),我希望这两个昂贵的操作并行发生。

自然,一个简单的List构造函数不会并行执行:

List(apiRequest1(q), apiRequest2(q))

并行集合可以提供帮助吗?还是我应该寻找期货之类的东西?我能想到的使用并行集合的唯一方法似乎很老套:

 List(q, q).par.zipWithIndex.flatMap((q) =>
   if (q._2 % 2 == 0) apiRequest1(q._1) else apiRequest2(q._1)
 )

其实,万事俱备,或许也不是那么糟糕……

4

3 回答 3

14

你为什么不写

List(apiRequest1 _, apiRequest2 _).par.map(_(q))
于 2011-10-23T21:10:59.340 回答
2

快速而肮脏的解决方案:

scala> def apiRequest1(q: Query): Option[Result] = { Thread.sleep(1000); Some(new Result) }
apiRequest1: (q: Query)Option[Result]

scala> def apiRequest2(q: Query): Option[Result] = { Thread.sleep(3000); Some(new Result) }
apiRequest2: (q: Query)Option[Result]

scala> val f = List(() => apiRequest1(q), () => apiRequest2(q)).par.map(_())
f: scala.collection.parallel.immutable.ParSeq[Option[Result]] = ParVector(Some(Result@1f24908), Some(Result@198c0b5))
于 2011-10-23T21:14:43.663 回答
0

如果您只有两个或少量调用,我不确定它实际上是否会并行工作,并行化有一个阈值,并且它可能会以如此小的集合顺序工作,因为它不值得并行化开销(它无法知道,因为它取决于您要运行的操作,但对收集操作设置阈值是合理的)。

于 2011-10-24T06:37:41.117 回答