|
Project Information
|
//Define.h
#ifndef _MEMORYPOOL_DEFINE_H_
#define _MEMORYPOOL_DEFINE_H_
namespace MemoryPool
{
;
typedef unsigned char byte;
typedef unsigned int uint;
}; // namespace MemoryPool
#endif _MEMORYPOOL_DEFINE_H_
=======================================================================================
#include "Define.h"
namespace MemoryPool
{
;
class Node
{
public:
Node()
:prev_(NULL)
,next_(NULL)
{
}
virtual ~Node()
{
prev_ = NULL;
next_ = NULL;
}
Node* Next()
{
return next_;
}
Node* Prev()
{
return prev_;
}
void Attach(Node* node)
{
node->prev_ = this;
node->next_ = next_;
next_ = node;
}
private:
Node* next_;
Node* prev_;
};
=======================================================================================
| <----------- allocated memory ---------> |
----------------------------------------------------------
PieceBlock | head | piece 1 | piece 2 | piece 3 | ..... | tail |
----------------------------------------------------------
class PieceBlock : public Node
{
public:
PieceBlock(uint block_id);
virtual ~PieceBlock();
void* get_piece(uint index, uint piece_size, uint piece_count);
uint GetID()
{
return id_;
}
private:
void* piece_;
uint id_;
};
PieceBlock::PieceBlock(uint block_id)
:id_(block_id)
,piece_(NULL)
{
}
PieceBlock::~PieceBlock()
{
if (piece_)
{
free(piece_);
piece_ = NULL;
}
}
void* PieceBlock::get_piece(uint index, uint piece_size, uint piece_count)
{
if (index >= piece_count)
return NULL;
if (piece_ == NULL)
{
uint block_size = piece_size * piece_count;
piece_ = malloc(block_size);
assert(piece_);
memset(piece_, 0, block_size);
}
byte* position = (byte*)piece_;
position += index * piece_size;
return position;
}
=======================================================================================
PieceBlock -> PieceBlock -> ... ->PieceBlock -> NULL
head tail
class Container
{
public:
Container(uint piece_size, uint piece_count);
virtual ~Container();
void ReSize(uint piece_count);
protected:
void* At(uint index);
private:
PieceBlock* head_;
PieceBlock* tail_;
PieceBlock* position_;
uint piece_size_;
uint piece_count_;
};
Container::Container(uint piece_size, uint piece_count)
:piece_size_(piece_size)
,piece_count_(piece_count)
,head_(NULL)
,tail_(NULL)
,position_(NULL)
{
assert(piece_count_);
assert(piece_size_);
}
Container::~Container()
{
Node* node = head_;
while (node)
{
Node* temp = node;
node = node->Next();
delete temp;
}
}
void Container::ReSize(uint piece_count)
{
assert(piece_count);
if (piece_count_ == piece_count)
return;
piece_count_ = piece_count;
Node* node = head_;
while (node)
{
Node* temp = node;
node = node->Next();
delete temp;
}
head_ = NULL;
tail_ = NULL;
position_ = NULL;
}
void* Container::At(uint index)
{
assert(piece_count_);
uint block_index = index / piece_count_;
if (head_ == NULL)
{
if (block_index != 0)
{
assert(0);
return NULL;
}
head_ = new PieceBlock(0);
position_ = head_;
tail_ = head_;
}
if (position_->GetID() != block_index)
{
if (block_index == tail_->GetID())
{
position_ = tail_;
}
else if (block_index < tail_->GetID())
{
Node* node = head_;
while (node)
{
if (((PieceBlock*)node)->GetID() == block_index)
{
position_ = (PieceBlock*)node;
break;
}
node = node->Next();
}
}
else
{
if (block_index == (tail_->GetID() + 1))
{
PieceBlock* next = new PieceBlock(block_index);
assert(next);
if (next)
{
tail_->Attach(next);
tail_ = next;
position_ = next;
}
}
else
{
assert(0);
return NULL;
}
}
}
uint piece_index = index % piece_count_;
return position_->get_piece(piece_index, piece_size_, piece_count_);
}
=======================================================================================
class Allocator : public Container
{
public:
Allocator(uint piece_size, uint piece_count);
virtual ~Allocator();
void* Pop();
private:
uint piece_index_;
};
Allocator::Allocator(uint piece_size, uint piece_count)
: Container(piece_size, piece_count)
, piece_index_(0)
{
}
Allocator::~Allocator()
{
}
void* Allocator::Pop()
{
void* piece = At(piece_index_);
if (piece)
{
++piece_index_;
return piece;
}
return NULL;
}
=======================================================================================
class Repository : public Container
{
public:
Repository(uint piece_count);
virtual ~Repository();
void* Pop();
void Push(void* ptr);
private:
uint piece_index_;
};
Repository::Repository(uint piece_count)
: Container(sizeof(void *), piece_count)
, piece_index_(0)
{
}
Repository::~Repository()
{
}
void* Repository::Pop()
{
if (piece_index_ <= 0)
return NULL;
uint idx = piece_index_ - 1;
void** piece = (void**)At(idx);
if (piece)
{
piece_index_ = idx;
return *piece;
}
return NULL;
}
void Repository::Push(void* ptr)
{
void** piece = (void**)At(piece_index_);
if (piece)
{
*piece = ptr;
++piece_index_;
}
}
}; // namespace MemoryPool
#endif _MEMORYPOOL_CONTAINER_H_
=======================================================================================
#ifndef _MEMORYPOOL_MEMORYPOOL_H_
#define _MEMORYPOOL_MEMORYPOOL_H_
#include <new>
#include <assert.h>
#include "./Define.h"
#include "./Container.h"
namespace MemoryPool
{
;
class Destroyer
{
public:
Destroyer()
{
}
virtual ~Destroyer()
{
}
virtual void Destroy(void* ptr, void* object) = 0;
};
-----------------------------------------------------
| Destroyer * | piece * | Destroyer * | piece * | ....
-----------------------------------------------------
template <class T>
class MemoryPool : public Destroyer
{
private:
enum { default_piece_count = 8, };
public:
static MemoryPool<T>* Instance()
{
static MemoryPool<T> static_pool;
return &static_pool;
}
MemoryPool()
: allocator_(sizeof(T) + sizeof(Destroyer*), default_piece_count)
, repository_(default_piece_count/2)
{
}
virtual ~MemoryPool()
{
}
void ReSize(uint piece_count)
{
allocator_.ReSize(piece_count);
repository_.ReSize(piece_count/2);
}
T* Create()
{
Destroyer** temp = (Destroyer**)repository_.Pop();
if (temp == NULL)
{
temp = (Destroyer**)allocator_.Pop();
if (temp == NULL)
return NULL;
}
*temp = this;
T* object = (T*)(temp + 1);
// 생성자 호출.
new(object) T();
return object;
}
virtual void Destroy(void* ptr, void* object)
{
assert(ptr);
assert(object);
if (ptr && object)
{
// 소멸자 호출.
T* temp = (T*)object;
temp->T::~T();
repository_.Push(ptr);
}
}
private:
Allocator allocator_;
Repository repository_;
};
void DeleteMemory(void* ptr)
{
assert(ptr);
Destroyer** temp = (Destroyer**)ptr;
Destroyer* owner = *(temp - 1);
if (owner == NULL)
{
//이중 삭제
assert(0);
}
else
{
owner->Destroy(temp - 1, ptr);
*(temp - 1) = NULL;
}
}
}; // namespace MemoryPool
#define NkReSize(type_, n) MemoryPool::MemoryPool<type_>::Instance()->ReSize(n);
#define NkNew(type_) MemoryPool::MemoryPool<type_>::Instance()->Create();
#define NkDelete(ptr_) MemoryPool::DeleteMemory(ptr_);
#endif _MEMORYPOOL_MEMORYPOOL_H_
=======================================================================================
#include <stdio.h>
#include <Windows.h>
#include "../SourceFile/MemoryPool/MemoryPool.h"
typedef unsigned int uint;
class A
{
public:
A()
{
}
virtual ~A()
{
}
int a;
int b;
int c;
};
class B : public A
{
public:
B()
{
}
virtual ~B()
{
}
int d;
int e;
};
int main()
{
const uint cnt = 100000;
A* ar[cnt] = {0,};
NkReSize(B, 100);
do
{
{
DWORD start = ::GetTickCount();
for (uint i = 0 ; i < cnt ; ++i)
{
A* b = new B();
ar[i] = b;
}
DWORD delta = ::GetTickCount() - start;
DWORD start2 = ::GetTickCount();
for (uint j = 0 ; j < cnt ; ++j)
{
delete ar[j];
}
DWORD delta2 = ::GetTickCount() - start2;
printf("new : %d, delete : %d\r\n", delta, delta2);
}
{
DWORD start = ::GetTickCount();
for (uint i = 0 ; i < cnt ; ++i)
{
A* b = NkNew(B);
ar[i] = b;
}
DWORD delta = ::GetTickCount() - start;
DWORD start2 = ::GetTickCount();
for (uint j = 0 ; j < cnt ; ++j)
{
NkDelete(ar[j]);
}
DWORD delta2 = ::GetTickCount() - start2;
printf("nk new : %d, delete : %d\r\n", delta, delta2);
}
}
while (getchar());
return 0;
}result.......not bad... |