std::vector< MyObject* > my_vector;
哪个不是空的,我想分配并推送一定数量的MyObject *。
我知道要推送的对象数量。有没有比这更好的方法(优化/更快):
int object_count = 10000;
for(int index = 0; index < object_count; index++)
{
my_vector.push_back(new MyObject());
}
就像在一次调用malloc中为所有MyObject分配一样,然后将结果memcpy给my_vector。 有什么想法吗?
更新 我的问题是召唤新的10000次。我希望能够分配一大块内存并将内存交换到my_vector的末尾。
答案 0 :(得分:3)
你可以在向量中保留足够的空间,因此它只会分配一次内存。使用std :: unique_ptr&lt;&gt;:
也是一种好习惯std::vector<std::unqiue_ptr<MyObject> > my_vector;
int object_count = 10000;
my_vector.reserve(object_count);
for(int index = 0; index < object_count; index++)
{
my_vector.push_back(std::unique_ptr<MyObject>(new MyObject()));
}
更新:如果您无法使用(或者不想)使用unique_ptr,只需在代码中添加reserve以预分配内存。
更新2 :据我所知,您希望避免new MyObject()
中的内存分配。一个可行的解决方案是以下(不适用于实际应用):
// a very simple example
class Pool {
public:
Pool() : array(new MySpecObjects[10000]), counter(10000); {}
MySpecObject* get() {
--counter;
return array[counter];
}
void reset() {
counter = 10000;
}
MySpecObject* array;
size_t counter;
};
static Pool* getPool() {
static Pool pool;
return pool;
}
std::vector<MyObject* > my_vector;
int object_count = 10000;
my_vector.reserve(object_count);
for(int index = 0; index < object_count; index++) {
my_vector.push_back(getPool().get()));
}
这是一个简化的例子,它不是线程安全的,Pool会在程序关闭时清除它的内存。它背后的想法类似于flyweight gof pattern,see boost for example
更新3 :也许更好的解决方案是在这里使用intrusive lists。然后,您需要做的就是预先分配对象的向量:
class MyObject : public boost::intrusive::list_base_hook<> {
...
};
// MySpecObject1 and MySpecObject2 inherit MyObject
std::vector<MySpecObject1> objs1(10000);
std::vector<MySpecObject2> objs2(10000);
...
typedef boost::intrusive::list<MyObject> BaseList;
BaseList list;
for (MyObject& ref : objs1) {
list.push_back(ref);
}
for (MyObject& ref : objs2) {
list.push_back(ref);
}
请注意,BaseList不拥有自己的节点。当你对它执行push_back时,list只是将一个对象链接到现有列表,不执行任何分配。
答案 1 :(得分:1)
标准功能std::generate_n
似乎符合您的需求:
// Reserve space in vector to prevent unneeded reallocations
my_vector.reserve(my_vector.capacity() + 10000);
// Use back inserter to automatically call push_back each time
// generate_n assigns value. Lambda will be called at each iteration
// constructing new object.
std::generate_n(std::back_inserter(my_vector), 10000,
[]() { return new MyObject; });