2013-02-05 3 views
2

현재 서면으로 작성한 라이브러리에서 폴리곤 계열이 아닌 내 작은 객체는 객체 풀 내에서 unique_ptr의 벡터로 할당됩니다. 이제 분명히 새로운 것을 여러 번 부르는 데 많은 오버 헤드가 있기 때문에 이것을 바꾸고 싶습니다. 좀 더 효율적인 방법은 다음과 같습니다. 객체를 풀 (벡터에 저장 (예 : vector<Object>))하거나 객체가 필요할 때 ID를 통해 객체를 생성하는 방법이 궁금합니다. 그리고 생성 된 많은 객체가 있음을 주목하십시오. 필요할 때 객체를 생성스택에 작은 객체를 힙 (한 번)에 만들면 더 효율적입니까?

:

내가이 일을해야한다, 내 말은 무엇입니까?

Object ObjectFactory::create() 
{ 
    return Object(nextId(), getParent()); 
} 

Object ObjectFactory::get(unsigned id) 
{ 
    return Object(id, getParent()); 
} 

또는 (모두 포함 된 이러한 객체 64-128 비트가 작고 참고하면 ID 및 기준 부모 객체/포인터) I 구체적있어 어떤

Object& ObjectFactory::create() 
{ 
    // get the next id of the object 
    unsigned id = nextId(); 

    // resize (if necessary) 
    if(_objects.size() <= id) 
    { 
     _objects.resize(id + 1); 
     _objects[id]._parent = getParent(); 
    } 

    return _objects[id]; 
} 

Object& ObjectFactory::get(unsigned id) 
{ return _objects[id]; } 

우려하고있다 : Object의 재창조가 훨씬 과장 될까?

+2

이 질문에서 하나 개의 누락 된 세부 사항이 있습니다 : 당신은 두 가지 버전을 실행할 때, 너무 많은 하나의 오버 헤드가 무엇입니까? –

+2

잠깐 동안 힙이 스택보다 100 배 느리다 고 가정하십시오. 귀하의 응용 프로그램은 너무 자주이 차이점을 발견합니까? 그렇지 않은 경우 깨끗하고 사용하기 쉽고 인터페이스를 유지하는 것이 더 중요하지 않습니까? – PlasmaHH

+2

연속 된 메모리에 객체를 저장하면 (std :: vector가 보증 함) 메모리의 조각난 영역에 객체를 저장하는 대신 엄청난 속도 향상을 가져올 수 있습니다. – borisbn

답변

0

@ LokiAstari가 맞습니다. 크기를 조정할 때 포인터에 문제가있는 것이 확실합니다.

내가 이해하지 못하는 부분이 있습니다. 당신은 개체 풀을 사용하고 있지만 너무 많은 새로운 문장에 문제가 있다고 말합니다. 객체 풀을 사용하는 경우 새로운 문장을 피하는 것이 정확하다고 말할 수 있습니까?

저는 전문가가 아니지만 일반적으로 자신의 할당 자 (강제적으로 어두운면) 구현과 관련된 더 나은 해결책이있을 수 있지만 제 제안입니다. std::deque과 같은 컨테이너를 사용하면 크기 조정시 포인터/참조의 유효성을 보장 할 수 있습니다.

많은 개체 (풀)의 초기 크기 조정부터 시작하여 필요에 따라 후속 크기 조정을 수동으로 처리하거나 (미리 정의 된 크기의 청크로 용량 확장) 또는 새 문을 수락 할 수 있습니다. 많이는 안되며, emplace_back 메소드를 사용하십시오.

ID로 개체를 삽입/삭제하는 일이 많은지 잘 모르겠습니다. 그렇다면 std::unordered_map을 사용해보세요. 여기

는 예 std::deque을 사용하고 있습니다 :

#include <iostream> 
#include <deque> 

#define POOL_RESERVE 1000 


// Data storage for your object 
struct MyObjectData 
{ 
    double some_data; 
}; 


// Container returned by the factory 
struct MyObject 
{ 
    typedef MyObjectData data_type; 

    unsigned id; 
    data_type* data; 

    MyObject(): id(0), data(0) {} 
    MyObject(const unsigned& id_, data_type* data_): id(id_), data(data_) {} 

    void set(const unsigned& id_, data_type* data_) 
     { id = id_; data = data_; } 
}; 


// MyObject Pool 
class MyObjectPool 
{ 
public: 

    typedef MyObjectData data_type; 

    MyObjectPool(): count(0) { pool.resize(POOL_RESERVE); } 

    void get(const unsigned& id, MyObject& obj) 
     { 
      // Check requested index 
      if (id >= count) 
       obj.set(0, 0); 
      else 
       obj.set(id, &pool[id]); 
     } 

    void create(MyObject& obj) 
     { 
      // Create new data container if needed 
      if (count++ >= pool.size()) pool.emplace_back(); 

      // Return next available object 
      obj.set(count-1, &pool[count-1]); 
     } 

private: 

    unsigned count; 
    std::deque<data_type> pool; 
}; 


// MyObject factory 
class MyObjectFactory 
{ 
    typedef MyObjectFactory self; 
    static MyObject local; 

    static MyObjectPool& get_instance() 
     { 
      static MyObjectPool pool; 
      return pool; 
     } 

public: 

    static MyObject get(const unsigned& id) 
     { 
      self::get_instance().get(id,local); 
      return local; 
     } 

    static MyObject create() 
     { 
      self::get_instance().create(local); 
      return local; 
     } 
}; 

// Define static variable 
MyObject MyObjectFactory::local = MyObject(); 


// Usage example 
int main() 
{ 
    MyObject a,b,c; 

    a = MyObjectFactory::create(); 
    b = MyObjectFactory::create(); 
    c = MyObjectFactory::get(1); 
} 
+0

''std :: deque''를''std :: vector''보다 왜 사용합니까? 나는 내가 선택한 두 번째 옵션을 사용할 것이라고 생각한다. BTW 나는 싱글 톤을 전혀 사용할 필요가 없다고 생각합니다. 단지 제 생각입니다. –

+0

내가 말했듯이,'std :: vector'는'resize' 나'push_back' 후에 포인터/참조의 유효성을 보장하지 않기 때문에'std :: deque'를 사용해야합니다. 내 생각에는 싱글 톤이 필요하다. 왜냐하면 풀이 명시 적으로 팩토리에 대한 참조를 전달하지 않고 액세스 할 수 있어야하기 때문이다 (그런데 명확하지 않고 위험하다). 프로그램을 모르는 경우에도 함수 나 메소드가 풀 객체를 선험적으로 액세스 할 수 있어야합니다. 공장을 실수로 복사하면 어떻게됩니까? @LokiAstari의 코멘트를 읽었습니까? 두 번째 해결 방법은 유효하지 않습니다. – Sheljohn

+0

@ Sh3john, 나는 그것을 읽었다. 단지 그것이 크기 조정과 push_back에서 내부적으로 객체를 움직 였다는 것을 몰랐다. –