在scala中并行移动两条路径

时间:2013-01-29 18:32:14

标签: scala performance

我有两个树(路径),由类似

的节点定义
trait Node {
  def getParent : Node
  def op(n:Node)
}

我希望向上移动两个节点,直到父级并行为null,如:

伪:

def simultanousUp(/*var*/ a:Node,/*var*/ b:Node) = 
     while(a != null) {
          a.op(b); 
          a = a.getParent;
          b = if(b!=null) b.getParent else null /*or throw somthing*/;
      }

问题:在scala中有更优雅和/或高效的方法吗?

为避免误解:这不是关于并发执行的问题!

3 个答案:

答案 0 :(得分:3)

父级不能为空。

首先,我们是正确的:

trait Node {
  def parent : Option[Node]
  def op(n:Node) // what does op mean ? what is the return type of op ? 
                 //cannot be Unit
}

然后

@scala.annotation.tailrec 
//it makes sure it's tailrec, so it can be optimized
def simultanousUp(a:Node, b:Node): (Node,Node) = {
      a.op(b)
      (a.parent, b.parent) match {
          case (Some(pa), Some(pb)) => simultanousUp(pa,pb)
          case _ => (a,b)
      }

}

答案 1 :(得分:3)

@annotation.tailrec final def simultaneousUp(a: Node, b: Node) {
  if (a != null && b != null) {
    a op b
    simultaneousUp(a.getParent, b.getParent)
  }
  // Throw exception or whatever on mismatched lengths?
}

答案 2 :(得分:-1)

如果op是一个简单的操作,则无法有效地并行运行,因为遍历会占用大量时间。

如果op是一个更复杂(即耗时)的操作,您可以并行执行。但是,您需要先将其转换为ParVector或类似的东西。


我认为没有更高效的遍历方式。然而,Stream有一个更优雅(但可能不那么高效)的解决方案:

def pathTo(start: Node): Stream[Node] = start.getParent match{
    case null => Stream.empty
    case nextPoint => Stream.cons(start, pathTo(nextPoint))
}