반응형
56바이트의 Enemy Class를 기준으로 new/delete와 Object Pool을 비교한 코드입니다.
오브젝트 생성 횟수는 1000만 개를 기준으로 했으며
1. new/delete 생성 Object Pool 생성 속도 비교
2. new/delete 해제 Object Pool 반환 속도 비교
3. 오브젝트의 재사용을 위한 new/delete 재할당 Object Pool 재사용 속도 비교
4. new/delete 해제 Object Pool 반환 속도 비교
로 비교하였습니다.
테스트 결과, Object Pool의 재사용은 동적 할당 대비 약 3배 이상의 성능 향상을 보여주었습니다.
이는 매번 힙 메모리를 요청하는 new/delete 방식이 가진 오버헤드를 피할 수 있기 때문입니다.
단, Object Pool은 한 번 확보한 메모리를 계속 유지하므로, 메모리 사용량이 제한적인 환경에서는 풀의 크기를 신중히 조절해야 합니다.
작성 코드
#include <iostream>
#include <vector>
#include <time.h>
#include "JSSort.h"
using namespace std;
class Enemy
{
public:
Enemy() {}
~Enemy() {}
Enemy(int hp, int attack, int defense, int speed)
: hp(hp), attack(attack), defense(defense), speed(speed) {}
public:
int gethp() const { return hp; }
int getattack() const { return attack; }
int getdefense() const { return defense; }
int getspeed() const { return speed; }
void sethp(int hp) { this->hp = hp; }
void setattack(int attack) { this->attack = attack; }
void setdefense(int defense) { this->defense = defense; }
void setspeed(int speed) { this->speed = speed; }
public:
void Init(int hp, int attack, int defense, int speed) {
this->hp = hp;
this->attack = attack;
this->defense = defense;
this->speed = speed;
}
void print() const
{
cout << "hp: " << hp << ", attack: " << attack << ", defense: " << defense << ", speed: " << speed << endl;
}
private:
int hp;
int attack;
int defense;
int speed;
string name;
};
class EnemyPool
{
public:
EnemyPool(size_t size) {
pool.reserve(size);
for (size_t i = 0; i < size; ++i)
pool.push_back(new Enemy());
}
~EnemyPool() {
for (auto e : pool)
delete e;
}
Enemy* GetEnemy() {
if (pool.empty())
return new Enemy(); // 풀 다 썼을 때 예외 처리
Enemy* e = pool.back();
pool.pop_back();
return e;
}
void ReturnEnemy(Enemy* e) {
pool.push_back(e);
}
private:
vector<Enemy*> pool;
};
// --------- 테스트 헬퍼 ----------
template<typename T>
bool is_sorted_vec(const std::vector<T>& a) {
for (size_t i = 1; i < a.size(); ++i) if (a[i - 1] > a[i]) return false;
return true;
}
int main()
{
const size_t COUNT = 10000000; // 1000만 번 테스트
// 1. new/delete 첫 번째 생성
clock_t start1 = clock();
vector<Enemy*> enemies1;
enemies1.reserve(COUNT);
for (size_t i = 0; i < COUNT; i++)
enemies1.emplace_back(new Enemy(1, 2, 3, 4));
clock_t end1 = clock();
clock_t start2 = clock();
for (auto e : enemies1)
delete e;
enemies1.clear();
clock_t end2 = clock();
// 2️. Object Pool 첫 번째 생성
EnemyPool pool(COUNT);
vector<Enemy*> enemies2;
enemies2.reserve(COUNT);
clock_t start3 = clock();
for (size_t i = 0; i < COUNT; i++)
{
Enemy* e = pool.GetEnemy();
e->Init(1, 2, 3, 4);
enemies2.emplace_back(e);
}
clock_t end3 = clock();
clock_t start4 = clock();
for (auto e : enemies2)
pool.ReturnEnemy(e);
enemies2.clear();
clock_t end4 = clock();
// 3️. new/delete 재사용 테스트
clock_t start5 = clock();
for (size_t i = 0; i < COUNT; i++)
enemies1.emplace_back(new Enemy(1, 2, 3, 4));
clock_t end5 = clock();
clock_t start6 = clock();
for (auto e : enemies1)
delete e;
enemies1.clear();
clock_t end6 = clock();
// 4️. Object Pool 재사용 테스트
clock_t start7 = clock();
for (size_t i = 0; i < COUNT; i++)
{
Enemy* e = pool.GetEnemy();
e->Init(1, 2, 3, 4);
enemies2.emplace_back(e);
}
clock_t end7 = clock();
clock_t start8 = clock();
for (auto e : enemies2)
pool.ReturnEnemy(e);
enemies2.clear();
clock_t end8 = clock();
// 결과 출력
cout << "\n==== [ 1회차 ] ====\n";
cout << "new/delete 생성 : " << (double)(end1 - start1) / CLOCKS_PER_SEC << "초\n";
cout << "Object Pool 생성 : " << (double)(end3 - start3) / CLOCKS_PER_SEC << "초\n";
cout << "new/delete 해제 : " << (double)(end2 - start2) / CLOCKS_PER_SEC << "초\n";
cout << "Object Pool 해제 : " << (double)(end4 - start4) / CLOCKS_PER_SEC << "초\n";
cout << "\n==== [ 2회차 (재사용) ] ====\n";
cout << "new/delete 재생성 : " << (double)(end5 - start5) / CLOCKS_PER_SEC << "초\n";
cout << "Object Pool 재사용 : " << (double)(end7 - start7) / CLOCKS_PER_SEC << "초\n";
cout << "new/delete 재해제 : " << (double)(end6 - start6) / CLOCKS_PER_SEC << "초\n";
cout << "Object Pool 재해제 : " << (double)(end8 - start8) / CLOCKS_PER_SEC << "초\n";
return 0;
}
반응형
'C++' 카테고리의 다른 글
C++ 삽입 정렬과 퀵 정렬 학습 (2) | 2025.08.13 |
---|---|
함수 포인터 (typedef, using, std::function) (1) | 2024.12.14 |
C++ Linked List (0) | 2024.12.07 |
OpenGL : Laplacian Smoothing & Taubin Smoothing (1) | 2024.11.24 |
cout 소수점 고정 (0) | 2024.11.24 |