我想提高列表和映射的特定用法的性能,其中项目的数量具有100000的硬限制.在这种情况下,STL默认分配器显然不是最佳选择,因为清理所有成千上万的小物件需要很长时间(> 10秒!).更不用说所有其他潜在问题了.
因此,显然要改进这一点,我可以预先分配正确的内存量以包含所有列表/映射节点.到目前为止,我已经能够实现默认分配器的工作版本(通过从std :: allocator_traits派生),它为每个节点使用alloc/free.但我正在努力找出如何修改它以允许"有状态"使用,例如,我非常简单的堆栈:
using namespace std; class MemPoolStack { public: size_t Size; size_t Mult; size_t Total; size_t Top; size_t Last; unique_ptrData; unique_ptr Nexts; MemPoolStack(size_t size, size_t mult) : Size(size), Mult(mult), Total(size * mult), Top(0), Last(0), Data(new byte[Total]), Nexts(new size_t[Size]) { } size_t& Next(size_t i) { return *(Nexts.get() + i); } void* Pop() { byte* p = nullptr; if(Top Last) Last=Top; } else { p = nullptr; } return p; } bool Push(void* p) { ptrdiff_t diff = (byte*)p - Data.get(); size_t index = ((size_t)diff / Mult); if(diff>=0 && index struct MemPool { typedef T value_type; MemPool() throw() {} template MemPool (const MemPool&) throw() {} template struct rebind { typedef MemPool other; }; //off-topic: why doesn't allocator_traits define this? T* allocate (size_t n) { return static_cast (malloc(n*sizeof(T))); } void deallocate (T* p, size_t n) { free(p); } }; template bool operator== (const MemPool &, const MemPool&) throw() {return true;} template bool operator!= (const MemPool &, const MemPool&) throw() {return false;}
我正在实例化我的列表和地图,如下所示:
list> Keys; map , MemPool > Map;
这MemPoolStack
本身并不是真正的问题,它可能有错误,但它仅仅是出于示例目的.关键是MemPoolStack
该类将a存储unique_ptr
到预分配的内存和一些其他成员变量.
问题在于我需要MemPoolStack
在MemPool
类中引用一些内容,因此Visual C++ 11映射或列表构建分配器的所有不同方式最终都会为MemPoolStack
每个列表或映射生成一个实例.然后我可以使用MemPoolStack::Pop()
in MemPool::allocate()
和MemPoolStack::Push()
in MemPool::deallocate()
.
我还需要一种方法来初始构造我的分配器,指定大小.我试图把一个shared_ptr
在MemPool
,但它结束了迷路的时候列表决定调用分配的默认构造函数...
我也愿意抛弃所有这些代码,以便为原始问题提供一个很好的替代解决方案.