您的位置:首页 > 移动开发 > Objective-C

发现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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐