发现boost::object_pool的效率很低!难道大师没有考虑效率的问题?
2009-04-10 19:45
218 查看
先不多说,看看我这一组测试结果:
我的机器是奔4 CPU3.0Hz, 内存1G
对象X的大小是1028个字节。
1)直接使用new 和 delete:
(1)先 new 10000 个X 对象,再 delete 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:47
Delete Time:31
New Time:63
Delete Time:15
New Time:47
Delete Time:16
New Time:47
Delete Time:15
New Time:47
Delete Time:16
New Time:32
Delete Time:15
New Time:78
Delete Time:16
New Time:47
Delete Time:16
New Time:62
Delete Time:16
New Time:47
Delete Time:15
2)使用我自己写的一个简单的内存池:
(1)先 poll.malloc 10000 个X 对象,再 poll.free 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:15
Delete Time:0
New Time:16
Delete Time:0
New Time:16
Delete Time:15
New Time:0
Delete Time:0
New Time:0
Delete Time:0
New Time:16
Delete Time:0
New Time:15
Delete Time:0
New Time:0
Delete Time:16
New Time:0
Delete Time:15
New Time:0
Delete Time:0
2)使用boost::object_pool:
(1)先 p.malloc 10000 个X 对象,再 p.free 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:63
Delete Time:13156
New Time:0
Delete Time:12328
New Time:0
Delete Time:12219
New Time:15
Delete Time:12422
New Time:16
Delete Time:12750
New Time:15
Delete Time:13203
New Time:16
Delete Time:12719
New Time:15
Delete Time:12922
New Time:16
Delete Time:13672
New Time:0
Delete Time:12953
我真不敢相信boost::object_pool的效率会如此低,它的free操作实在太耗时间了,这能用吗?还是我的测试方法不对!
熟悉boost的高手们也来分析一下boost::object_pool, 它的free为什么会这么忙? 下面是我的测试代码和自己写的内存池(在vc6.0下编译运行成功),清高手指点!
#include <windows.h>
#include <assert.h>
#include <vector>
#include <boost/pool/object_pool.hpp>
#include <iostream>
#include <list>
class X
{
private:
int a;
char s[1024];
public:
X()
{
a = 10;
//std::cout<<"X/n";
}
X(int A )
{
a = A;
//std::cout<<"X/n";
}
~X()
{
//std::cout<<"~X/n";
}
void display() {std::cout<<a<<std::endl;}
};
template <typename T>
class cpoll
{
public:
typedef std::list<char*> LIST;
typedef struct _MEM_NODE
{
struct _MEM_NODE* next;
T* data;
}MEM_NODE, *PMEM_NODE;
cpoll() : m_elem_count(0), m_next_count(10)
{
init();
}
cpoll(int elem_next_count) : m_elem_count(0), m_next_count(elem_next_count)
{
init();
}
~cpoll()
{
LIST::iterator it, end = m_list.end();
for (it=m_list.begin(); it!=end; ++it)
delete [] (*it);
}
T* malloc()
{
T* p = _malloc();
new(p)T(); //调用构造函数
return p;
}
template<typename T1>
T* malloc(T1 t1)
{
T* p = _malloc();
new(p)T(t1);
return p;
}
//想要支持更多的参数,就自己加吧! ^_^
//...
void free(T* pt)
{
assert(pt);
pt->~T();//析构
PMEM_NODE p = PMEM_NODE((char*)pt-sizeof(PMEM_NODE));
p->next = m_free_node;
p->data = pt;
m_free_node = p;
}
private:
void init()
{
const int size = (sizeof(T)+sizeof(MEM_NODE)-sizeof(T*))*m_next_count;
m_free_node = PMEM_NODE(new char[size]);
assert(m_free_node);
m_list.push_back((char*)m_free_node);
m_free_node->data = (T*)((char*)m_free_node+sizeof(PMEM_NODE));
m_free_node->next = NULL;
PMEM_NODE p = m_free_node;
for (int i=0; i<m_next_count-1; ++i)
{
p->next = PMEM_NODE((char*)p+sizeof(T)+sizeof(MEM_NODE)-sizeof(T*));
p = p->next;
p->data = (T*)((char*)p+sizeof(PMEM_NODE));
p->next = NULL;
}
m_elem_count += m_next_count;
}
T* _malloc()
{
if (NULL == m_free_node)
{
//再分配一组内存
init();
}
T* p = m_free_node->data;
m_free_node = m_free_node->next;
return p;
}
private:
int m_elem_count;
int m_next_count;
LIST m_list;
PMEM_NODE m_free_node;
};
void func()
{
std::cout<<"sizeof(X)="<<sizeof(X)<<std::endl;
const int count = 10000;
const int N = 10;
cpoll<X> poll(count);
boost::object_pool<X> p;
#define USE_POLL 2
#if USE_POLL == 1 //使用new 和 delete
for (int k=0; k<N; ++k)
{
std::vector<X*> v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
v.push_back(new X());
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
{
delete v[i];
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
#if USE_POLL == 2 //使用我自己写的内存池
for (int k=0; k<N; ++k)
{
std::vector<X*>v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
X* p = poll.malloc();
v.push_back(p);
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
{
poll.free(v[i]);
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
#if USE_POLL == 3 //使用boost库里的内存池
for (int k=0; k<N; ++k)
{
std::vector<X*> v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
X* t = p.malloc();
/*注意;X的构造函数不会被调用,仅仅是分配大小为sizeof(X)
的内存块。如果需要调用构造函数(像new一样),应该调用
construct。比如:*/
new(t)X();
v.push_back(t);
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
4000
{
X* x = v[i];
x->~X();
p.free(x);
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
}
int main()
{
func();
return 0;
}
我的机器是奔4 CPU3.0Hz, 内存1G
对象X的大小是1028个字节。
1)直接使用new 和 delete:
(1)先 new 10000 个X 对象,再 delete 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:47
Delete Time:31
New Time:63
Delete Time:15
New Time:47
Delete Time:16
New Time:47
Delete Time:15
New Time:47
Delete Time:16
New Time:32
Delete Time:15
New Time:78
Delete Time:16
New Time:47
Delete Time:16
New Time:62
Delete Time:16
New Time:47
Delete Time:15
2)使用我自己写的一个简单的内存池:
(1)先 poll.malloc 10000 个X 对象,再 poll.free 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:15
Delete Time:0
New Time:16
Delete Time:0
New Time:16
Delete Time:15
New Time:0
Delete Time:0
New Time:0
Delete Time:0
New Time:16
Delete Time:0
New Time:15
Delete Time:0
New Time:0
Delete Time:16
New Time:0
Delete Time:15
New Time:0
Delete Time:0
2)使用boost::object_pool:
(1)先 p.malloc 10000 个X 对象,再 p.free 10000个X对象。
(2)重复(1)10次!
(3)结果:
sizeof(X)=1028
New Time:63
Delete Time:13156
New Time:0
Delete Time:12328
New Time:0
Delete Time:12219
New Time:15
Delete Time:12422
New Time:16
Delete Time:12750
New Time:15
Delete Time:13203
New Time:16
Delete Time:12719
New Time:15
Delete Time:12922
New Time:16
Delete Time:13672
New Time:0
Delete Time:12953
我真不敢相信boost::object_pool的效率会如此低,它的free操作实在太耗时间了,这能用吗?还是我的测试方法不对!
熟悉boost的高手们也来分析一下boost::object_pool, 它的free为什么会这么忙? 下面是我的测试代码和自己写的内存池(在vc6.0下编译运行成功),清高手指点!
#include <windows.h>
#include <assert.h>
#include <vector>
#include <boost/pool/object_pool.hpp>
#include <iostream>
#include <list>
class X
{
private:
int a;
char s[1024];
public:
X()
{
a = 10;
//std::cout<<"X/n";
}
X(int A )
{
a = A;
//std::cout<<"X/n";
}
~X()
{
//std::cout<<"~X/n";
}
void display() {std::cout<<a<<std::endl;}
};
template <typename T>
class cpoll
{
public:
typedef std::list<char*> LIST;
typedef struct _MEM_NODE
{
struct _MEM_NODE* next;
T* data;
}MEM_NODE, *PMEM_NODE;
cpoll() : m_elem_count(0), m_next_count(10)
{
init();
}
cpoll(int elem_next_count) : m_elem_count(0), m_next_count(elem_next_count)
{
init();
}
~cpoll()
{
LIST::iterator it, end = m_list.end();
for (it=m_list.begin(); it!=end; ++it)
delete [] (*it);
}
T* malloc()
{
T* p = _malloc();
new(p)T(); //调用构造函数
return p;
}
template<typename T1>
T* malloc(T1 t1)
{
T* p = _malloc();
new(p)T(t1);
return p;
}
//想要支持更多的参数,就自己加吧! ^_^
//...
void free(T* pt)
{
assert(pt);
pt->~T();//析构
PMEM_NODE p = PMEM_NODE((char*)pt-sizeof(PMEM_NODE));
p->next = m_free_node;
p->data = pt;
m_free_node = p;
}
private:
void init()
{
const int size = (sizeof(T)+sizeof(MEM_NODE)-sizeof(T*))*m_next_count;
m_free_node = PMEM_NODE(new char[size]);
assert(m_free_node);
m_list.push_back((char*)m_free_node);
m_free_node->data = (T*)((char*)m_free_node+sizeof(PMEM_NODE));
m_free_node->next = NULL;
PMEM_NODE p = m_free_node;
for (int i=0; i<m_next_count-1; ++i)
{
p->next = PMEM_NODE((char*)p+sizeof(T)+sizeof(MEM_NODE)-sizeof(T*));
p = p->next;
p->data = (T*)((char*)p+sizeof(PMEM_NODE));
p->next = NULL;
}
m_elem_count += m_next_count;
}
T* _malloc()
{
if (NULL == m_free_node)
{
//再分配一组内存
init();
}
T* p = m_free_node->data;
m_free_node = m_free_node->next;
return p;
}
private:
int m_elem_count;
int m_next_count;
LIST m_list;
PMEM_NODE m_free_node;
};
void func()
{
std::cout<<"sizeof(X)="<<sizeof(X)<<std::endl;
const int count = 10000;
const int N = 10;
cpoll<X> poll(count);
boost::object_pool<X> p;
#define USE_POLL 2
#if USE_POLL == 1 //使用new 和 delete
for (int k=0; k<N; ++k)
{
std::vector<X*> v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
v.push_back(new X());
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
{
delete v[i];
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
#if USE_POLL == 2 //使用我自己写的内存池
for (int k=0; k<N; ++k)
{
std::vector<X*>v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
X* p = poll.malloc();
v.push_back(p);
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
{
poll.free(v[i]);
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
#if USE_POLL == 3 //使用boost库里的内存池
for (int k=0; k<N; ++k)
{
std::vector<X*> v;
v.reserve(count);
DWORD dwtick = GetTickCount();
for (int i=0; i<count; ++i)
{
X* t = p.malloc();
/*注意;X的构造函数不会被调用,仅仅是分配大小为sizeof(X)
的内存块。如果需要调用构造函数(像new一样),应该调用
construct。比如:*/
new(t)X();
v.push_back(t);
}
std::cout<<"New Time:"<<(GetTickCount()-dwtick)<<std::endl;
dwtick = GetTickCount();
for (i=0; i<count; ++i)
4000
{
X* x = v[i];
x->~X();
p.free(x);
}
std::cout<<"Delete Time:"<<(GetTickCount()-dwtick)<<std::endl;
}
#endif
}
int main()
{
func();
return 0;
}
相关文章推荐
- 电路板焊接完成发现CPU没有工作,需要从哪些方面考虑解决这个问题?
- boost object pool的destroy() 效率太慢了
- 在网上找了个java小游戏的实例,敲完后发现没有main,自己加了个后,无法运行请问是什么问题 [ Java SE]
- boost中静态库编译没有-fPIC选项的问题解决方案
- 谷歌:没有发现 GMail 服务端出问题
- boost的pool和object_pool
- 给出现el表达式异常,但自我检查没有发现任何问题的朋友的忠告
- 发现了DeferWindowPos的一个问题,MSDN没有说明
- 自己考虑招人的事情,才发现自己简历问题出在什么地方
- 递归解决输出一个字符串的全排列问题(缺陷:没有考虑字符串中字符重复的问题)
- C++内存管理变革(4):boost::object_pool与gc allocator
- 关于Ibatis中的executeForObject方法使用时,需要考虑空的问题!
- [iOS] performSelector:withObject:afterDelay:调用没有作用的问题及解决方法
- [iOS] performSelector:withObject:afterDelay:调用没有作用的问题及解决方法
- 解决JPA 注解开发 Myeclipse 2017 C9 出现没有发现持久化单元中定义的名为 问题
- Dcook -> MJRefresh iOS10的系统上每次下拉刷新后没办法完全恢复Normal 状态 Y轴距离上总是相差20左右...(楼主个人也使用的MJ,表示暂时没有发现这个问题)
- 微软还是没有发现自己的问题!
- boost pool, object_pool实现
- C++内存管理变革(4):boost::object_pool与gc allocator