2012-04-07 45 views
0

我剖析我的比赛,看来我在这里度过一个良好的时间:优化获取绝对矩形的Widget?

const Rectangle Widget::getAbsoluteRectangle() const 
0.01s  { 
      Point absLocation; 

0.00s   absLocation = getLocation(); 

      if(!getParent()) 
      { 
       return Rectangle(absLocation.getX(),absLocation.getY(), 
        getSize().getWidth(),getSize().getHeight()); 
      } 

      const Widget* parent = this; 
      int eX = 0; 
      int eY = 0; 

      while(parent->getParent() != NULL) 
      { 
0.02s    parent = parent->getParent(); 

0.01s    eX = parent->getMargin(SIDE_LEFT); 
0.04s    eY = parent->getMargin(SIDE_TOP); 

0.03s    absLocation.setX(absLocation.getX() + parent->getLocation().getX() + eX); 
0.04s    absLocation.setY(absLocation.getY() + parent->getLocation().getY() + eY); 
      } 

0.02s   return Rectangle(absLocation,getSize()); 
0.01s  } 

我想到也许缓存的这个结果和无效它时,其父母一方移动或调整,但首先我我想知道是否有明显的优化。

谢谢

回答

1

你的问题是,你每次重新计算父母的位置。你需要做的是一个递归算法来一次计算它们。例如:

class Widget { 
public: 
    Rectangle AbsolutePosition; 
    Rectangle RelativePosition; 
    std::vector<Widget*> children; 

    void ComputePositions(Rectangle ParentPosition) { 
     ComputeAbsoluteFromParentAndRelative(ParentPosition); 
     std::for_each(children.begin(), children.end(), [&](Widget* child) { 
      child->ComputePositions(AbsolutePosition); 
     }); 
    } 
}; 

使用这种方法,每个插件有它只是计算的位置,准确地一次,目前的绝对位置已经被缓存。另外,如果需要,循环可以平行化,因为每次迭代都是独立的。最后,您可以轻松控制调用的级别,而不必每次都在根目录中调用该级别。