我找到了一个similar question,但它有一个似乎更简单的情况,昂贵的操作始终是相同的。就我而言,我想收集一些我希望并行执行的昂贵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)
)
实际上,在所有条件相同的情况下,也许这并不是那么糟糕......
答案 0 :(得分:14)
你为什么不写
List(apiRequest1 _, apiRequest2 _).par.map(_(q))
答案 1 :(得分: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))
答案 2 :(得分:0)
如果你只有两个或少量的调用,并不存在并行化的阈值,我不确定它是否会实际并行工作,它可能会按照这么小的集合顺序工作,理由是它是不值得并行开销(它不能知道,因为它取决于你想要运行的操作,但是在收集操作上有一个阈值是合理的。)