쿼드 트리를 구현 중입니다. 원시 포인터를 사용하는 버전에서 스마트 포인터와 참조를 사용하는 내 초안 (전체 버전은 here으로 볼 수 있음)을 다시 구현했습니다.이 경우 포인터가 더 느린 이유
하지만 새로운 나무를 채우는 것이 분명히 최대 2 배 느려지므로이 경우가 어떨까요?
이전 버전의 코드 :
// returns if coordinates fit in the tree
const bool contains(const double &x, const double &y, const double &w, const double &h) const {
return (this->x < x &&
this->y < y &&
this->x + this->w > x + w &&
this->y + this->h > x + h);
}
// returns if an element fits in the tree
const bool contains(const std::shared_ptr<Rectangle> &rect) const {
return contains(rect->getX(), rect->getY(), rect->getW(), rect->getH());
}
// inserts an element in the tree
const bool insert(const std::shared_ptr<Rectangle> &rect) {
// if rect is too big for this quadtree
if(!contains(rect)) {
auto sp = getParent();
if(sp == nullptr) {
return false;
}
return sp->insert(rect);
}
// if element theoretically fits in subtree
else if(rect->getW() < getW()/2 && rect->getH() < getH()/2) {
if(!subtrees[0]) {
generateSubtrees();
}
for(const auto &subtree: subtrees) {
if(subtree->contains(rect)) {
return subtree->insert(rect);
}
}
}
children.insert(children.end(), rect);
return true;
}
void generateSubtrees() {
subtrees[0] = std::make_shared<QuadTree>(getW()/2.0f, getH()/2.0f, getX(), getY(), this);
subtrees[1] = std::make_shared<QuadTree>(getW()/2.0f, getH()/2.0f, getX() + getW()/2.0f, getY(), this);
subtrees[2] = std::make_shared<QuadTree>(getW()/2.0f, getH()/2.0f, getX(), getY() + getH()/2.0f, this);
subtrees[3] = std::make_shared<QuadTree>(getW()/2.0f, getH()/2.0f, getX() + getW()/2.0f, getY() + getH()/2.0f, this);
}
이 버전 트리를 충전 시간은 약이다 1000
요소의 경우 0.001367
초.
그럼 I이 기능을 구현 재 :
는// Returns if a Rectangle fits in the tree
const bool contains(const Rectangle *rect) const {
return (this->x < rect->x &&
this->y < rect->y &&
this->x + this->w > rect->x + rect->w &&
this->y + this->h > rect->y + rect->h);
}
// Inserts an element in the tree
const bool insert(Rectangle *rect) {
if(!contains(rect) && parent == nullptr) {
return false;
}
if(rect->w < this->w/2.0f && rect->w < this->w/2.0f) {
if(children[0]==nullptr){
generateSubtrees();
}
for(const auto child: children) {
if(child->contains(rect)) {
return child->insert(rect);
}
}
}
elements.push_back(rect);
return true;
}
// Generate the subtrees
void generateSubtrees() {
children[0] = new Quadtree(w/2.0f, h/2.0f, x, y, this);
children[1] = new Quadtree(w/2.0f, h/2.0f, x+w/2.0f, y, this);
children[2] = new Quadtree(w/2.0f, h/2.0f, x, y+w/2.0f, this);
children[3] = new Quadtree(w/2.0f, h/2.0f, x+w/2.0f, y+w/2.0f, this);
}
1000
요소 버전을 채우는 시간이 소요 CA. 0.00312
초.
아시다시피 포인터를 사용하는 두 번째 버전은 훨씬 느립니다.
PS : 나는
insert(new Quadtree::Rectangle(std::rand()%999, std::rand()%999, 1, 1))
와
insert(std::make_shared<Rectangle>(std::rand()%999, std::rand()%999, 1, 1))
과 새와 루프 (버전 2) 오래 된 나무 (버전 1)을 입력합니다.
성능 저하의 원인이 어디에 있는지 알려주실 수 있습니까?
"훨씬 느린"속도는 얼마나 느 립니 까? 그리고 최적화가 활성화되어 컴파일 되었습니까? –
OP 상태 : 0.00312s 대 0.00137s. 개인적으로, 나는 그 작은 숫자에 기초를 두는 것을 아주 조심할 것이지만 나는 최적화 전문가가 아닙니다. – Chowlett
왜 1ms와 3ms의 차이에 대해 걱정하고 있습니까? 귀하의 사용자가 그 차이를 느낄 것이라고 생각합니까? –