我有一个类型。我在应用程序的不同部分实例化它,但我在某个地方依次遍历所有部分。我不知道到底会有多少人。如何创建一个存储100个对象块的分配器并根据需要提供指针?
我已尝试使用类固醇的简单工厂进行此类方法但goes over 5 seconds:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <thread>
#include <mutex>
using namespace std;
template<class T>
struct Item {
T data;
bool alive = true;
int id = 0;
};
template<class T>
class ItemFactory {
vector<Item<T>> items;
unordered_map<int, int> item_ids;
unsigned int lastCounter=0;
int removedCounter=0;
mutex m;
public:
int CreateItem() {
lock_guard<mutex> l(m);
auto result = lastCounter++;
Item<T> item;
item.id = result;
items.push_back(item);
item_ids[result] = items.size()-1;
return result;
}
T& GetItem(int id) {
lock_guard<mutex> l(m);
return items[item_ids[id]].data;
}
void RemoveItem(int id) {
lock_guard<mutex> l(m);
items[item_ids[id]].alive = false;
removedCounter++;
if(removedCounter>=1000) {
removedCounter = 0;
auto end = remove_if(items.begin(), items.end(), [](const Item<T>& item){
return !item.alive;
});
items.erase(end, items.end());
auto size = items.size();
item_ids.clear();
for(auto i = 0; i < size; i++) {
item_ids[items[i].id]=i;
}
}
}
};
struct demo {
string bla;
float arr[256];
};
int main() {
ItemFactory<demo> f;
for(int i = 0; i < 50000; i++) {
auto id = f.CreateItem();
auto id2 = f.CreateItem();
auto & i1 = f.GetItem(id);
auto & i2 = f.GetItem(id2);
i1.bla = "abra kadabra bum";
i2.bla = "bla bla bla";
f.RemoveItem(id);
}
cout << "!!!" << endl;
for(int i = 0; i < 25000; i++) {
auto id = i + i*2;
auto & i1 = f.GetItem(id);
i1.bla = "abra kadabra bum";
f.RemoveItem(id);
}
return 0;
}
有没有办法获得连续的内存块,但在插入/删除时更有效?
答案 0 :(得分:1)
我会查找如何编写内存池分配器,或使用众多可用内容之一,例如Boost Pool:http://www.boost.org/doc/libs/1_59_0/libs/pool/doc/html/index.html
C++11 memory pool design pattern?
通常,您可以根据需要分配大块内存并分发指针;如果你知道你永远不会释放记忆,它可以被优化。如果你真的一直需要连续的内存,即使你偶尔释放,你唯一能做的就是重新分配内存并重新洗牌,如果经常这样做会非常昂贵。