Boost 对象池技术缺陷及改进。附代码。
近日研究了 boos t对象池技术 ---- boost::object_pool 。发现他并没有想象中的那么完美。算法的在效率上存在很大的问题。
首先:初始化 Chunk 时,遍历每一个元素并赋值地址。在 Chunk 块很大时,还是很浪费时间的。
其次:在 Free 时,他要找到链表的前一个节点,但由于其设计的是单链表结构,所以查找前一个节点只能是从头节点依次遍历。这个速度就慢的惊人了。可以做个这样的测试。
struct Test {char array[128];}
boost::object_pool<Test> pp;
static const int TEST_SIZE = 10000;
Test* array[TEST_SIZE];
for (int i(0); i < TEST_SIZE; ++i)
{
array[i] = pp.malloc();
}
for (int i(0); i < TEST_SIZE; ++i)
{
pp.free(array[i]);
}
上面这段测试的代码,运行的时间为 9331 毫秒,测试机器配置如下。
CPU: Intel(R) Core(TM)2 4300@ 1.80GHz
MEM: 2.00 GB
跟踪代码会看到。object_pool::free() 中调用了一个叫 find_prev() 的函数。里面一个 while(true) 在遍历所有节点,就为了找到前一个节点。尽管 object_pool 的设计思路很好,得其算法并不理想。而且甚至比直接 new 和 delete 还慢。(这里先不考虑碎片问题)。
我对该功能做了重新设计,效率提高了很多,对象创建的越多,效率提高的越快。
同样上面的测试代码,在我的 MemPool 中执行只需要 3 毫秒。下面是该代码的下载页面。
http://download.csdn.net/source/1908652
目前测试来看,功能还算安全。然而我的水平很有限,不敢说这样的设计就一定好,很希望朋友们能帮我看看,是否还有没有考虑到的问题。也欢迎兄弟来讨论一下对象池的技术。^_*
QQ:25400260