2012-04-07 35 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); 
     }); 
    } 
}; 

使用這種方法,每個插件有它只是計算的位置,準確地一次,目前的絕對位置已經被緩存。另外,如果需要,循環可以平行化,因爲每次迭代都是獨立的。最後,您可以輕鬆控制調用的級別,而不必每次都在根目錄中調用該級別。