內存池

#pragma once
#include<vector>
template<class T>
class ObjectPool
{
protected:
	struct Node
	{
		void* _memory;// 內存塊
		Node* _next; //指向下一塊節點的指針
		size_t _objectNum;//統計內存對象的個數
		Node(size_t objectNum)
			:_objectNum(objectNum)
			,_next(NULL)
		{
			_memory=malloc(_iteamSize*_objectNum);
		}
	};
	size_t _countIn;//當前節點已用的個數
	Node* _frist;
	Node* _last;
	size_t _maxNum; //節點申請內存塊最大大小
        static size_t _iteamSize;//單個對象的大小
	T* _lastDelete;
public:
	static size_t initIteam()
	{
		if(sizeof(T)>=sizeof(void*))
			return sizeof(T);
		else
			return sizeof(void*);
	}
	ObjectPool(size_t initNum=32,size_t maxNum=10000)
		:_countIn(0)
		,_maxNum(maxNum)
		,_lastDelete(NULL)
	{
		if(initNum>maxNum)
			initNum=maxNum;
		_frist=new Node(initNum);
		_last=_frist;
	}
	T* New()
	{
		if(_lastDelete)
		{
			T* obj=_lastDelete;  
			_lastDelete=*((T**)_lastDelete);
			return new (obj)T();//new的定位表達式
		}
		else  //沒有釋放的內存對象
		{
			if(_countIn>=_last->_objectNum)
				AllocateNewNode();
			T* obj=(T*)((char*)_last->_memory+_countIn*_iteamSize);
		    _countIn++;
			return new (obj)T();  //obj是地址,T是類型
		}
	}
	void AllocateNewNode()
	{
		size_t objectNum=_last->_objectNum*2;
		if(objectNum>_maxNum)
			objectNum=_maxNum;
		_last->_next=new Node(objectNum);
		_last=_last->_next;
		_countIn=0;
	}
	void Delete(T* ptr)
	{
		if(ptr)
		{
			*((T**)ptr)=_lastDelete;
			_lastDelete=ptr;
		}
	}
	void Destory()
	{
		Node* cur=_frist;
		while(cur)
		{
			Node* del=cur;
			cur=cur->_next;
			delete del;
		}
		_countIn=0;
		_frist=_last=NULL;
	}
	~ObjectPool()
	{
		Destory();
	}
};
template<class T>   //靜態的成員變量必須在類外進行初始化
size_t  ObjectPool<T>::_iteamSize =ObjectPool<T>::initIteam ();


// 測試內存對象池的常規使用和內存對象的重複使用
void TestObjectPool()
{
	vector<string*> v;

	ObjectPool<string> pool;
	for (size_t i = 0; i < 32; ++i)
	{
		v.push_back(pool.New());
		printf("Pool New [%d]: %p\n", i, v.back());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}

	for (size_t i = 0; i < 32; ++i)
	{
		v.push_back(pool.New());
		printf("Pool New [%d]: %p\n", i, v.back());
	}

	v.push_back(pool.New());
	printf("Pool New : %p\n", v.back());
}

#include <Windows.h>

// 針對當前的內存對象池進行簡單的性能測試
void TestObjectPoolOP()
{
	size_t begin , end;
	vector<string*> v;
	const size_t N = 10000;
	v.reserve(N);

	cout<<"pool new/delete==============================="<<endl;
	// 反覆申請釋放5次
	begin = GetTickCount();
	ObjectPool<string> pool;
	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(pool.New());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(pool.New());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(pool.New());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(pool.New());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(pool.New());
	}

	while (!v.empty())
	{
		pool.Delete(v.back());
		v.pop_back();
	}


	end = GetTickCount();
	cout<<"Pool:"<<end - begin<<endl;

	cout<<"new/delete==============================="<<endl;
	begin = GetTickCount();

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(new string);
	}

	while (!v.empty())
	{
		delete v.back();
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(new string);
	}

	while (!v.empty())
	{
		delete v.back();
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(new string);
	}

	while (!v.empty())
	{
		delete v.back();
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(new string);
	}

	while (!v.empty())
	{
		delete v.back();
		v.pop_back();
	}

	for (size_t i = 0; i < N; ++i)
	{
		v.push_back(new string);
	}

	while (!v.empty())
	{
		delete v.back();
		v.pop_back();
	}

	end = GetTickCount();
	cout<<"new/delete:"<<end - begin<<endl;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章