用于加速 VC++ STL 的自定义块分配器






4.63/5 (19投票s)
一个块分配器,可与 STL 容器配合使用,显著提高了执行大量数据插入和提取操作的程序的运行速度。
引言
block_allocator
是一个自定义 STL 分配器,可与 Microsoft VC++ 中实现的 STL 配合使用。block_allocator
不会按节点进行分配,而是以固定大小的块分配内存,并按请求提供这些块的一部分。与默认分配器相比,速度通常提高了 40%。块的大小由用户设置,不应太小(会降低速度提升)也不应太大(会浪费内存)。进行实验,找出最适合您应用程序的大小。block_allocator
可以替换以下容器中的默认分配器
列表
,set
,multiset
,map
,multimap
,
// block allocated list of ints with chunks of 1024 elements std::list<int,block_allocator<int,1024> > l;常规容器和块分配的容器可以共存而不会出现问题。
与 MSVC++ 6.0/7.0 的兼容模式
由于这些编译器附带的标准库存在限制,因此上述使用模式在此处不适用。要解决此问题,必须按以下步骤操作:对于每个支持的容器,都有一个关联的块分配容器,该容器是通过使用 `block_allocator` 从其派生出来的。您必须为每个要定义的容器定义一个激活宏,然后才能包含 *blockallocator.h*
list -> block_allocated_list
(宏DEFINE_BLOCK_ALLOCATED_LIST
),set -> block_allocated_set
(宏DEFINE_BLOCK_ALLOCATED_SET
),multiset -> block_allocated_multiset
(宏DEFINE_BLOCK_ALLOCATED_MULTISET
),map -> block_allocated_map
(宏DEFINE_BLOCK_ALLOCATED_MAP
),multimap -> block_allocated_multimap
(宏DEFINE_BLOCK_ALLOCATED_MULTIMAP
),
要在您的应用程序中使用基于块分配的 STL,请定义相应的激活宏,包含 *blockallocator.h*,然后像这样更改您的声明:
list<type> -> block_allocated_list<type,chunk_size>
set<key> -> block_allocated_set<key,chunk_size>
multiset<key> -> block_allocated_multiset<key,chunk_size>
map<key,type> -> block_allocated_map<key,type,chunk_size>
multimap<key,type> -> block_allocated_multimap<key,type,chunk_size>
其中 `chunk_size` 是块的大小。您也可以输入其他可选的模板参数(有关更多信息,请参阅 MSVC++ STL 文档)。
MSVC++ 6.0/7.0 兼容模式也可在 MSVC++ 7.1 中使用,因此在将旧代码移植到 7.1 时,您无需修改 `block_allocator` 相关的代码。
多线程问题
每个块分配的容器实例都使用自己的 `block_allocator`,因此只要您的程序方便地保护其容器免受并发访问(或者没有两个线程访问同一个容器实例),就不会出现多线程问题。这与常规 STL 类的情况相同(请记住,容器上的操作不受 `CRITICAL_SECTION` 或类似机制的保护),因此,关键在于:如果您的程序在没有 `block_allocator` 的情况下是多线程安全的,那么使用它之后也会继续保持安全。
版本历史
- 2000 年 2 月 29 日 - 1.1
- 在 CodeProject 上首次发布。
- 2001 年 3 月 22 日 - 1.2
- 包含 `operator==` 和 `operator!=` 的定义。缺少这些定义会在调用 `list::swap()` 和类似方法时导致链接错误。有趣的是,没有人报告过这个看似重要的问题,要么是 `swap()` 使用频率不高,要么是很少有人使用 `block_allocator`!
- 2006 年 10 月 25 日 - 1.3
- 现在 `block_allocator` 可与 MSVC++ 7.1 和 8.0 配合使用。感谢 James May 协助测试此新版本代码。
- 2006 年 10 月 30 日 - 1.4
- 修复了 `block_allocated_list`、`block_allocated_set` 等中一些错误地设置为 `private` 的 `typedef`。