Является ли более эффективным выделение небольшого объекта в стеке по сравнению с созданием его в куче (один раз)?

В настоящее время с библиотекой, которую я написал, мои маленькие объекты (которые не являются полиморфными) размещаются в пуле объектов в векторе с unique_ptr«S. Теперь, очевидно, я хочу изменить это, потому что очевидно, что вызовы нового так много раз требуют много времени. Мне любопытно, если это более эффективно: кэшировать объекты в пуле (сохранить его в векторе, т.е. vector<Object>) или создайте объект, когда это необходимо, с помощью его идентификатора. И обратите внимание, что здесь создано много объектов.

Я имею в виду, должен ли я делать это:

Создать объект при необходимости? (Обратите внимание, что эти объекты маленькие, 64-128 бит, так как все содержит идентификатор и ссылку / указатель на родительский объект)

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

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

или же:

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

Решение

@LokiAstari прав, у вас явно проблемы с указателями на изменение размера.

Есть кое-что, чего я не понимаю; вы говорите, что используете пул объектов, но у вас есть проблемы со слишком большим количеством новых операторов. Если вы используете пул объектов, я бы сказал, что именно для того, чтобы избежать новых операторов, нет?

Вот мои предложения, хотя я не эксперт и, возможно, найдутся лучшие решения, включающие реализацию вашего собственного распределителя (темная сторона силы ..). Вы можете использовать контейнер как std::deque, что обеспечивает действительность указателей / ссылок на изменение размера.

Вы начнете с первоначального изменения размера множества Объектов (вашего пула), и вы можете либо вручную обработать последующее изменение размера при необходимости (расширение емкости с помощью кусков предварительно определенного размера), либо принять новые операторы тогда, если вы знаете, что не много, и используйте метод emplace_back.

Я также не знаю, много ли вы вставляете / удаляете объекты с вашими идентификаторами. Если это так, вы можете рассмотреть возможность использования 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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]