在堆栈上分配一个小对象比在堆上创建它(一次)更有效吗
Is it more efficent to allocate a small object on the stack as apposed to creating it on the heap (once)?
目前,在我编写的库中,我的小对象(不是多态的)在对象池中以unique_ptr
的向量进行分配。现在很明显,我想改变这一点,因为这么多次打新电话显然有很多过头的地方。我很好奇是否更有效:将对象缓存在池中(将其存储在向量中,即vector<Object>
),或者在需要时通过其ID创建对象。请注意,创建了很多对象。
我的意思是,我应该这样做吗:
需要时创建对象?(请注意,这些对象很小,64-128位,因为包含的只是一个ID和一个指向父对象的引用/指针)
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
的重新创建会引起太多的混乱吗?
@LokiAstari是对的,您的指针在调整大小时显然有问题。
有些事情我不明白;你说你正在使用一个对象池,但你有太多新语句的问题。如果你使用对象池,我会说这正是为了避免新的语句,不是吗?
以下是我的建议,尽管我不是专家,而且可能有更好的解决方案,通常涉及您自己的分配器的实现(力量的黑暗面..)。您可以使用像std::deque
这样的容器,它可以确保指针/引用在调整大小时的有效性。
您将从大量对象(您的池)的初始大小调整开始,您可以在需要时手动处理后续的大小调整(使用预定义大小的块扩展容量),或者接受新语句,如果您知道不应该有很多,则使用template_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);
}
相关文章:
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- Microsoft ODBC 无法创建有效的句柄
- 创建加密安全密码.并验证它是否有效
- 创建字符串数组的有效方法
- 在递归函数中更有效地创建对象和对象数组?C++
- 有效创建数字签名的正确方法是什么?我可以使用DSA_sign_setup()吗?
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- 从 std::vector 创建 OpenCV 垫子的有效方法
- 给定一个创建的带有货物的链表,我需要使用函数检查实际序列或"train"是否有效
- C++,我正在尝试创建一个有效的.bmp输出文件
- 一个创建彩票游戏的程序,该彩票游戏可以有效地创建 10 套而没有任何重复?
- 在 OpenGL ES for Android 中运行时创建大型纹理的最有效方法
- OpenCV: cv::Mat 无法从看似有效的数据中创建矩阵
- Qt C++ - 创建 QList<Myclass> - 不是参数 'T 的有效模板类型参数
- 如何有效地从标准:d创建D3D缓冲区
- 我的代码有效,但 setter 不会创建新对象,所以我得到错误的结果
- 当从一个应用程序调用时,在DLL方法中创建COM接口指针是有效的,但当从另一个应用软件调用时则无效
- LeapMotion 创建有效设备 - >添加到有效控制器
- SDL和zlib问题,不能从zip创建有效的组结构
- 如何使用 C++11 创建有效的闭包