这取决于被评估的表达式的costly。在当前架构上,两个表达式涉及几条到几十条甚至数百条指令,无法有效地并行计算。因此,您应该始终确保您正在执行的工作量不会被并行化本身的成本所掩盖。
考虑到这一免责声明,在 Scala 2.10 中,您可以使用 Futures 来完成此操作:
val f = future { e1 }
val g = future { e2 }
(Await.result(f), Await.result(g))
请注意,不鼓励这种类型的计算(上面故意过于冗长!),因为它涉及阻塞,并且在没有有效延续概念的 JVM 等平台上阻塞通常代价高昂(尽管适用的情况超出了此答案的范围,可能超出了此回答者的范围)。在大多数情况下,您应该在 future 上安装一个回调,一旦它的值可用,就会调用它。你可以这样做:
val h = for {
x <- f
y <- g
} yield (x, y)
上面的h 是一个新的未来,一旦两者都可用,它将包含一个值的元组。
您可以将函数 par_tuple 重写为:
def par_tuple[E1, E2](e1: =>E1, e2: =>E2): Future[(E1, E2)] = {
val f = future { e1 }
val g = future { e2 }
val h: Future[(E1, E2)] = for {
x <- f
y <- g
} yield (x, y)
h
}
此方法返回您想要的元组的Future - 一个最终将包含您的表达式的元组的对象。你可以用其他计算进一步组合这个未来,或者如果你确定要阻止,你可以有另一个变体:
def par_tuple_blocking[E1, E2](e1: =>E1, e2: =>E2): (E1, E2) = Await.result(par_tuple(e1, e2))
在元组将来可用之前阻塞。
见more about futures, callbacks and blocking here。