사례를 통해 살펴보는 프로파일링과 최적화 ndc2013

117
사례를 통해 살펴보는 프로파일링과 최적화 넥슨 김이선 veblush at gmail

Upload: esun-kim

Post on 22-May-2015

4.080 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

사례를 통해 살펴보는 프로파일링과 최적화

넥슨

김이선

veblush at gmail

Page 2: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

BNB 프로그래머

카트라이더 리드 프로그래머

버블파이터 프로토타입

리드 프로그래머 에버플래닛

리드 프로그래머 던전엔파이터

테크니컬 디렉터 GTR

프로그래머

Page 3: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

오늘 할 이야기 ?

최적화를 어떻게 진행했는지 실제 사례를 들어 설명 아키텍쳐의 설명 혹은 프로파일링 툴 사용법에 대한 내용은 아님

Page 4: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

클라이언트 초기 구동 최적화

클라이언트 FPS 최적화

서버 몬스터 이동 최적화

조언

목차

Page 5: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

던전엔 파이터 (디버그 빌드) 초기 구동 시간 단축

Page 6: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

개발 이터레이션

코딩 빌드 초기구동 결과확인

F5 짧을 수록 좋다

Page 7: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

120초

코딩 빌드 초기구동 결과확인

F5

개발 이터레이션

Core i5 760 2.80GHz, 4GB RAM, G2 SSD, XP

Page 8: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

해결할 수 있는 문제인가?

이미 최적인지?

아니라면 최적에서 얼마나 먼 상태인지?

Page 9: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로그램 구동: 하드에 있는 내용을 메모리로

200MB

던파 (디버그) 클라이언트는 구동 직후 200MB 차지

Page 10: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

근데 하드가 제일 느리잖아

그래서 하드 속도 이상은 안 될꺼야…

200MB

60MBps

3.3초

Rule of Thumb

Page 11: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

120초 / 3.3초 =

36x

Page 12: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표

< 20초

Page 13: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

핫스팟 찾기

A hot spot in computer science is most usually defined as a region of a computer program

where a high proportion of executed instructions occur or

where most time is spent during the program's execution

(not necessarily the same thing since some instructions are faster than others)

- Wikipedia -

Page 14: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

가장 문제가 되는 부분을 고치는 것이

일 한 티가 남 효율이 좋음

A:90 B:10

30 10

90 1

3x

10x

Amdahl's law

2x

Page 15: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로파일링!

In software engineering, profiling ("program profiling", "software profiling") is a form of

dynamic program analysis that measures, for example, the space (memory) or time complexity of a program,

the usage of particular instructions, or frequency and duration of function calls.

The most common use of profiling information is to aid program optimization.

- Wikipedia -

Page 16: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

어떤 프로파일러를 사용할까?

= 어떤 최적화를 할지에 따라 다름

Page 17: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디자인

어셈블리

컴파일

코드

문제

레벨

탑랭커 3명 추려보이기

리스트를 정렬해 상위 3명 얻기

sort(list)[:3]

/Ox

예제

Page 18: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

typedef vector<pair<int, string>> Scores; void GetRanker(const Scores& l, Scores& r) { // sort(list)[:3] ScoreList m = l; sort(m.begin(), m.end(), Scores_less); r.assign(m.begin(), m.begin() + 3); }

코드 최적화

디자인 최적화

Page 19: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

코드 최적화

void GetRanker(const Scores& l, Scores& r) { vector<const Scores::value_type*> m(l.size()); for (size_t i=0, j=l.size(); i != j; ++i) m[i] = &(l[i]); sort(m.begin(), m.end(), pScoreList_less); for (size_t i=0; i < 3; i++) r.push_back(*m[i]); }

4x

Page 20: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디자인 최적화

void GetRanker(const Scores& l, Scores& r) { // 리스트를 순회하며 가장 높은 점수 3개 찾기 for (auto i=l.begin(), j=l.end(); i != j; ++i) { if (r.empty() || r.back().first < i->first) { auto j = upper_bound(r.begin(), r.end(), *i); r.insert(j, *i); if (r.size() > 3) r.pop_back(); } } }

+100x

Page 21: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디자인

어셈블리

컴파일

코드

문제

탑랭커 3명 추려보이기

리스트를 정렬해 상위 3명 얻기

sort(list)[:3]

/Ox

예제

SIMD? PREFETCH?

임의로 뽑은 100명중 상위 3명

순회만으로 상위 3명 얻기

sort(&list)[:3]

/Ox /NO_DEBUG

최적화

x4

x100

x1000

x3

x2

Page 22: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디자인

어셈블리

컴파일

코드

문제

여지 익숙도 레벨 툴여부

Page 23: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

CPU 프로파일러 레벨

CodeAnalyst VTune

Visual Studio Profiler Very Sleepy Glow Code

In-house Profiler

Brain

GPU 프로파일러

Perfhud Perfstudio GPA

PIX

X Engine Profiler

Eye

In-house Profiler 디자인

어셈블리

컴파일

코드

문제

Page 24: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

s = clock();

do_something_big();

print(clock() – s);

전체 뷰를 보기 위해

번거롭지만 무료

선택한 프로파일러

핫스팟 코드/함수 보기

무료, 간편

In-house Profiler AMD CodeAnalyst

Page 25: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

In-house Profiler

Page 26: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

AMD CodeAnalyst

Page 27: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

테스트 시나리오가 쉽게 반복되도록!

개선 정도를 쉽게 확인 할 수 있어야!

Page 28: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표설정 프로파일링 최적화 결과확인 & 검증

최적화 과정

Page 29: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

최적화 사례

문제확인 원인분석 해결

Page 30: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디버그에서 STL 이 느림

STL Debugging

Page 31: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

_ITERATOR_DEBUG_LEVEL (>= VS2012)

_SECURE_SCL, _HAS_ITERATOR_DEBUGGING (<= VS2010)

STL Debugging

Page 32: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

STL Debugging

Page 33: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디버그 빌드 때

_ITERATION_DEBUG_LEVEL = 2 → 1

STL Debugging

Checked & Debug

Checked

Page 34: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

zlib 등 라이브러리 함수가

프로파일러에 많이 등장함

Optimization Flag

Page 35: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

디버그 빌드라고 모든 모듈을

디버그 할 필요 없음!

Optimization Flag

Page 36: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

라이브러리중 신뢰도가 높으면서

빠른 성능이 필요한 것은

최적화 옵션을 사용한 빌드를 사용

Optimization Flag

Page 37: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Optimization Flag

Page 38: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로젝트 내부에 독립된 모듈로 존재하는 라이브러리는

모듈만 최적화 옵션을 사용해 성능 향상을 꾀함

Optimization Flag

Page 39: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

item_map[0] = Item();

// Item::Item() { clear(); }

// item_map = std::map<Item>

Big Constructor & Map

Page 40: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

item_map[0] = Item();

// item_map[0] – Item::Item() called

// Item() – Item::Item() called

// a = b – operator =

// ~Item() - Item()::~Item() called

Big Constructor & Map

Page 41: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

if item_map.has_key(0)

item_map[0].clear();

else

item_map[0];

Big Constructor & Map

Page 42: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

이상하게 debug.assert 함수가

CPU 를 많이 사용하고 있음

ASSERT

Page 43: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

#define ASSERT(b) \

debug.assert(b, _T(#b), …)

void debug::assert(b, …) {

if (b) return;

ASSERT

Page 44: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

#define ASSERT(b) \

if (b) ; else debug.assert(b, _T(#b), …)

ASSERT

Page 45: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

폰트 로딩에 CPU 를 많이 사용하고 있다

FontLoad

Page 46: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

void load_font(font) {

for (g in font-glyphs)

max_size = max(max_size, getsize(g));

}

FontLoad

Page 47: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

void load_font(font) {

if size_cache_map.has(font, size)

max_size = size_cache_map[font, size];

else

for (g in font-glyphs)

max_size = max(max_size, getsize(g));

log(“missing:”, font, size);

FontLoad

Page 48: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

ParseString 함수가 많은 시간을 소모

ParseString

Page 49: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

ParseString(String) → Key, Value

ParseString(“Key1>테스트”) → “Key1”, “테스트”

ParseString

// 주석

Key1>테스트

Key2>개행도\n됩니다\n하하하

Page 50: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

ParseString

길이 제한 검사 (strlen)

문자열 마지막의 ‘\n’ ‘\r’ 제거

문자열 앞 공백문자 건너뛰기

주석인지 검사

‘>’ 위치 찾기

키 길이 확인

‘>’ 앞뒤의 문자열 얻기 (string assign)

“\n” 를 찾고 개행 문자로 치환

Key1>테스트문자열입니다 scan

scan

scan

alloc

Page 51: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

ParseString

공백 건너뛰기

주석이거나 빈줄이면 리턴

‘>’ 위치 찾기

키가 없거나 너무 길면 에러

EOS 찾기 및 “\n”를 개행 문자로 치환

Key1>테스트문자열입니다

scan

Page 52: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

함수 load_data 가 CPU 를 많이 차지

Flex Performance

Page 53: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

void Read_Game_Data() {

for (file in files) {

d = load_data(file);

item = parse(d);

}

}

Flex Performance

Page 54: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Flex Performance

Data File

Data Grammar load_data function

Tokens

Flex

Options element := id | num | string

load_data() generated

[power] 1 5 [pos] 10 20

[power] 1 5 …

Page 55: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Flex Performance

Options

Page 56: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

load_data 생성에 최적화 옵션 사용

Flex Performance

Page 57: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표설정 프로파일링 최적화 결과확인 & 검증

검증

특히 라이브 상태라면 무엇보다 중요하다

Page 58: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

최적화 전 동작 = 최적화 후 동작

검증

Page 59: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

ParseString 의 예

// 기존 함수와 새 함수가 동일한

// 결과를 반환하는지 확인

ParseString(line, key, val);

ParseStringNew(line, key2, val2);

ASSERT(key == key2 && val == val2);

Page 60: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

15초 < 20초

2012.9 에 5초 도달

Page 61: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

마비노기2 (개발 빌드) 몬스터 200 마리 스폰 상태에서 FPS 올리기

Page 62: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

200 마리 몬스터

1fps (개발 빌드에서)

I7-2600 (3.40GHz), 8GB, GTS 450, W7-64bit

Page 63: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표

> 20fps

Page 64: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

어느정도 해결 가능한 것으로 추정 내부 프로파일러 정보를 통해 렌더링이

병목이 아닌 것은 알고 있었다

Page 65: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로파일러

AMD CodeAnalyst

VerySleepy

Intel VTune, Scaleform AMP 보조적으로 사용

Page 66: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로파일러

In-house Counter

In-house Profiler

Page 67: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

시작 시간 단축과 달리

매번 동일한 상황을 만들기 번거로우니 않으니.

F5 -> 게임 입장까지 절차 자동화

준비 (실행)

Page 68: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

프로파일러가 콜스택을 잘 보이도록

준비 (빌드 옵션)

• CL Global Optimization 끔

(켜 있으면 /Oy- 와 관계없이 FBO 가 되는 현상이 있음)

• CL Frame Buffer Omission 끔

(프로파일러가 콜 스택을 잘 보도록)

• LINK COMDAT Folding 끔

(Identical Function 이 합쳐지는 것 방지)

Page 69: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

몬스터 수 20 → 200 비교하기

배수가 아닌 항목을 찾자

20 200

Page 70: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표설정 프로파일링 최적화 결과확인 & 검증

최적화 과정

Page 71: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

최적화 사례

문제확인 원인분석 해결

Page 72: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Enum Constructor

단순 enum 타입

Page 73: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Enum Constructor

ValueType

Object

GC

virtual

AbnormalConditionType

Page 74: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Enum Constructor

AbnormalConditionType

ValueType

Page 75: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

진단 로그 범람

printf 류의 함수가 사용하는 함수

Page 76: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

DaignosticScene:

개발 보조도구로 거의 모든 게임 정보를

텍스트 형태로 볼 수 있는 로그

진단 로그 범람

Page 77: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

진단 로그 범람

msg = format(“%d %d %d”, pos)

diag_log(msg);

// if (diag_on)

// display_and_save_log(msg)

Page 78: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

진단 로그 범람

if (diag_on) {

msg = format(“%d %d %d”, pos)

diag_log(msg);

}

Page 79: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

PerformanceCounter Lock

Page 80: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

PerformanceCounter Lock

Counter* FindCounter(name) {

scope_lock(lock);

return map.find(name);

}

FindCounter(“update”)->Add(1);

Page 81: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

PerformanceCounter Lock

Counter* FindCounter(name) {

scope_read_lock(lock);

return map.find(name);

}

FindCounter(“update”)->Add(1);

Page 82: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

두 벡터의 각도를 구하는 함수에서 시간 소모!

두 벡터의 각도

Page 83: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

두 벡터의 각도

float getAngle(vec a, vec b) {

r = atan2f(a.y, a.x);

v = atan2f(b.y, b.x);

return r - v;

}

if (abs(getAngle(a, b)) < 0.2f);

Page 84: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

두 벡터의 각도

float getAngleCos(vec a, vec b) {

v = dot(a, b) / len(a) / len(b);

return v;

}

if (getAngleCos(a, b) < cosf(0.2f));

Page 85: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

게임 로직의 대부분의 함수가

전반적으로 느림

Object Component Locality

Page 86: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Object = Component*

Character = [Pos] [Status] [Equip] [Account] …

Monster = [Pos] [Status] [Equip] [AI] …

Object Component Locality

Page 87: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Object* CreateMonster(info) {

obj = new Object()

obj->create<PosComponent>();

obj->create<StatusComponent>();

return obj;

}

Object Component Locality

Object

Pos

Status

AI

Page 88: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

void ThinkMonster(Object* m) {

pc = m->get<PosComponent>();

sc = m->get<StatusComponent>();

ac = m->get<AIComponent>();

(pc … sc … ac…)

}

Object Component Locality

Object

Pos

Status

AI

Page 89: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Object Component Locality

Object Pos

Status AI

Object Pos

Status AI

Object Pos

Status AI

Page 90: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Object* CreateMonster(info) {

obj = new Object()

tls_obj = obj;

obj->create<PosComponent>();

void* Component::operator new(size_t s) {

return tls_obj->malloc(s);

}

Object Component Locality

Page 91: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

메모리 침범 디버깅을 위한 검사 코드가

CPU 를 많이 사용함

Allocator Guard

Page 92: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

메모리 침범 디버깅을 위해 guard 버퍼 사용

Allocator Guard

Chunk guard Chunk guard Chunk

0xabababab … ababab

Page 93: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Allocator Guard

bool memcheck(byte* p, int len) {

byte* e = p + len;

for (; p < e; ++p) {

if (*p != 0xab)

return false;

return true;

}

Page 94: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Allocator Guard

bool memcheck(byte* p, int len) {

dword* d = (dword*)p

dword* e = p + len / 4;

for (; d < e; ++d) {

if (*d != 0xabababab)

return false;

return true;

}

Page 95: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

몬스터간 충돌에 Kynapse 를 사용

Kynapse Collision

왜 원이 아니고 사각형인가? Collision_RectangularBody

Page 96: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Shape(r, r) vs Shape(r)

Kynapse Collision

Page 97: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Kynapse Collision

Page 98: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

검증 간단히 가능하지 않으면 대충 넘어감

(라이브가 아니라서… 그래서 한 번 터짐…)

Page 99: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

34fps > 20fps

Page 100: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

에버플래닛 몬스터 이동 서버 처리량 최적화

Page 101: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

MMORPG 는 필드에 몬스터가 가장 많음

몬스터는 대부분의 시간을 돌아다니거나 추적하며 보냄

때문에 개발 초기 단계부터

서버에서 처리 할 몬스터 이동에 대해 고민

Page 102: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

길 찾기 알고리즘 (몬스터가 현 위치에서 목표 지점 위치까지 어떻게 가는지)

Page 103: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
Page 104: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Athlon 64 x2 3800+ (2.0GHz), 2GB, XP

A* Hierarchical A* Go & Turn

81 ops 3,668 ops 488,281 ops

Page 105: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Go & Turn Hierarchical A*

Fail?

Page 106: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Go & Turn 으로 95% 이상 길 찾기 가능

서버에서 초당 (코어당) 400,000 번 길 찾기 가능

Page 107: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

Idle 상태의 몬스터 이동 최적화

Page 108: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
Page 109: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

t=0

t=10

t=20

f(t, pos, seed)

서버가 t, pos, seed 를 전송하면 클라이언트가

위치 계산 가능

이동에 대한 데이터를 더 이상 보낼 필요 없음

서버 부하 줄어듬

네트워크 부하 줄어듬

Page 110: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

나이스?

Page 111: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

조언

Page 112: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

목표설정 프로파일링 최적화 결과확인 & 검증

최적화 과정

목표가 있어야 작업이 종료됨

Rule of Thumb

적절한 툴/방법 찾기 상상력 동원 성능 향상 확인 및 지식화

검증은 라이브라면 더더욱!

Page 113: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

최적화 단계를 개발 단계에 넣을 것

최적화는 디버깅과 유사 → 나중에 하면 어렵다!

최저 사양 / 권장 사양 PC 를 옆에 두고

사용하는 것도 좋은 방법.

개발 단계

Page 114: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

성능 지표를 개발 / 라이브 단계에서

주기적으로 확인 필요

성능은 단순한 버그로도 급격하게

나빠질 수 있다.

개발 단계

Page 115: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

자주 불리는 함수는 최적화에 신경써야 초당 1000번 불리는 함수는 초당 1번 불리는 것에 1000배?

개발 단계

Page 116: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

설계 단계에서 성능 고려 이미 결정된 설계를 나중에 변경하기란 쉽지 않다

개발 단계

Page 117: 사례를 통해 살펴보는 프로파일링과 최적화 NDC2013

감사합니다!