프로파일러로 월드 성능 분석하기

# 학습 과정 소개

메이플스토리 월드의 루아 프로파일러가 스크립트를 중점적으로 분석하는 도구라면 성능 프로파일러(이하 프로파일러)는 현재 월드의 성능에 영향을 미칠 수 있는 요인들에 대해 전반적인 분석 결과를 보여줍니다. 프로파일링을 통해 월드 성능을 저하시키는 요인을 파악할 수 있고 이를 해결하여 월드 성능을 향상시킬 수 있습니다. 이번 과정에서는 프로파일러의 실행 및 사용 방법, 그리고 데이터 분석 결과를 해석하는 방법을 살펴보겠습니다.

##### 참고 가이드

[루아 프로파일러 활용하기](/docs/?postId=762)

# 프로파일러 실행하기

메이커에서 Panels - Profiler로 들어가면 프로파일러를 실행할 수 있습니다. [png](1689323157908f695d8d7daab4e6ca5b9a94148205fc1)

 [시작] 버튼을 눌러 플레이 상태로 진입한 뒤, 프로파일러의 [분석 레코드] 버튼을 누르면 기록이 시작되며, 한 번 더 누르면 기록이 중지됩니다. [png](1689323138212ef0142ece16f49dc939fcd1bb58e7b51)

> 더 알아보기 프로파일러 기록 중 정적 맵에서 인스턴스 맵으로 진입하거나, 반대로 인스턴스 맵에서 정적 맵으로 나오면 기록이 초기화됩니다. 

# 프로파일러 살펴보기

프로파일러 UI를 자세히 살펴봅시다. [png](1689748450026758f03f4c54c42338295dfa5bfd4a04a)

[{"대분류":"①분석 컨트롤 영역","번호":"1-1","항목":"Clear","설명":"이전에 기록된 분석 결과를 초기화합니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-2","항목":"분석 레코드","설명":"분석 기록을 시작합니다. 한 번 더 누르면 기록을 중지합니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-3","항목":"가장 오래된 타임라인","설명":"첫 타임라인으로 이동합니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-4","항목":"이전 타임라인","설명":"선택한 타임라인보다 바로 앞으로 이동합니다. Left Arrow 키로도 이동할 수 있습니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-5","항목":"다음 타임라인","설명":"선택한 타임라인보다 바로 다음으로 이동합니다. Right Arrow 키로도 이동할 수 있습니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-6","항목":"현재 타임라인","설명":"가장 마지막 타임라인으로 이동합니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-7","항목":"Timeline Indexes","설명":"타임라인 인덱스를 보여줍니다."},{"대분류":"①분석 컨트롤 영역","번호":"1-8","항목":"Profiler Config","설명":"[png](168956161350735b564735a634ee1b5fc873165db74c7)분석 차트 영역 설정 창입니다. X Axis Size : X축에 보이는 인덱스 개수를 설정합니다. Fill Chart : 그래프 채우기"},{"대분류":"①분석 컨트롤 영역","번호":"1-9","항목":"카테고리","설명":"Client : 클라이언트 영역의 분석 차트를 보여줍니다. Server : 서버 영역의 분석 차트를 보여줍니다."},{"대분류":"②분석 차트 영역","번호":"2-1","항목":"분석 항목 정보","설명":"분석 항목을 보여줍니다."},{"대분류":"②분석 차트 영역","번호":"2-2","항목":"차트","설명":"분석 항목 별 차트가 기록되는 영역입니다."},{"대분류":"②분석 차트 영역","번호":"2-3","항목":"타임라인 선택","설명":"마우스 왼쪽 클릭으로 원하는 타임라인을 선택할 수 있습니다. 마우스 오른쪽 클릭한 상태로 좌우 이동하면 그래프를 이동하며 볼 수 있습니다. 마우스 휠을 클릭한 상태로 왼쪽으로 이동하면 그래프가 축소되고 오른쪽으로 이동하면 확대됩니다."},{"대분류":"②분석 차트 영역","번호":"2-4","항목":"정보 툴팁","설명":"차트에 마우스 오버하면 툴팁으로 해당 타임라인의 상세 정보를 확인할 수 있습니다."},{"대분류":"②분석 차트 영역","번호":"2-5","항목":"가이드라인","설명":"안정적인 성능을 위해 권장하는 수치 정보를 가이드라인(하늘색 선)으로 보여줍니다. 가이드라인에 마우스를 올리면 툴팁으로 상세 정보를 확인할 수 있습니다."},{"대분류":"③분석 결과 영역","번호":"3-1","항목":"분석 상세 정보","설명":"2-1에서 선택한 항목의 상세 분석 결과를 보여줍니다. 고정 항목 이외에 추가로 추적하려는 항목은 Chase 체크박스를 활성화하여 기록할 수 있습니다."},{"대분류":"③분석 결과 영역","번호":"3-2","항목":"검색","설명":"검색어와 일치하는 항목을 표시합니다. 영어 대소문자는 구분하지 않습니다. [X] 버튼을 누르면 입력된 검색어를 모두 지웁니다."},{"대분류":"③분석 결과 영역","번호":"3-3","항목":"결과 펼치기 \/ 접기","설명":"분석 결과를 모두 펼치거나 접을 수 있습니다."}]

# 데이터 분석

유저가 각각 사용하는 PC, 모바일 기기의 사양이 매우 다양하기 때문에 같은 월드라도 플레이 환경의 쾌적함 정도는 상당히 달라질 수 있습니다. 하지만 대략적으로 분석 수치가 아래와 같을 경우 해당 월드의 성능을 어느 정도 판단할 수 있습니다. 아래의 수치는 대략적인 참고값으로 활용할 수 있으며, 그 이전에도 체감되지 않는 성능 하락은 발생할 수 있습니다.

### FPS (Client)

FPS는 클라이언트에서 측정하는 요소로 반응성 및 화면 재생과 관련이 있습니다.

  * 플레이할 때 화면 재생에 영향을 미칩니다. FPS가 떨어지면 화면 끊김이 발생할 수 있습니다.
  * 최소 30FPS를 유지하는 것을 권장합니다.



[{"항목":"World FPS","설명":"크리에이터의 로직을 처리하는 월드 코어의 FPS를 보여줍니다. 비효율적인 로직, 과도한 Sync Property, 실행 제어를 통해 다른 실행 공간의 함수를 호출하는 등 다양한 원인에 의해 FPS가 떨어질 수 있습니다."},{"항목":"Engine FPS","설명":"주로 입력, 네트워킹, 그래픽을 연산하는 엔진의 FPS를 보여줍니다. 엔티티의 양이 너무 많거나, 과도한 이펙트 및 파티클을 사용하는 경우에 Engine FPS가 크게 떨어질 수 있습니다."}]

### Tick (Server)

Tick은 서버의 초당 연산 수행 횟수를 보여주는 수치로 서버와 통신 반응성에 큰 영향을 미칩니다.

  * Server Tick이 낮아질수록 Ping(네트워크 지연 시간)이 높아진 것과 비슷하게 느껴질 수 있습니다.
  * 월드의 비효율적인 로직, 과도한 Sync Property, 다른 실행 공간 사용 및 잘못된 로직으로 발생한 패킷 홍수로 Server Tick이 떨어질 수 있습니다.
  * PvP나 대전 장르와 같이 반응성이 중요한 경우, 최소 30 Server Tick을 유지하기를 권장합니다.
  * 실시간 반응성이 크게 중요하지 않은 월드라면 최소 10 Server Tick을 유지하기를 권장합니다.
  * Server Tick이 높을수록(최대 60Tick) 서버 반응성이 좋아집니다.

  
> **더 알아보기** >패킷 홍수(Packet Flodding)란 매우 많은 양의 패킷(초당 약 10만 개 이상)이 송신 또는 수신되는 것을 말합니다. 클라이언트나 메이커에서 테스트 플레이를 하는 도중에는 더 적은 양의 패킷도 성능에 영향을 줄 수 있습니다. > 패킷 홍수는 주로 매 프레임이나 Tick마다 다른 실행 공간의 함수를 호출하는 경우 쉽게 발생합니다. > [png](1689732427563cd559f693ea145369ebb2c7a75cd1e0d) > 위 그림은 User1의 정보가 다른 User2, User3에게 전달되고, User2와 User3의 정보도 각각 다른 유저들에게도 전달될 때 대략적인 패킷 전달 모습입니다. 위의 상황은 한 프레임 또는 Tick 당 유저 한 명이 한 번의 패킷을 발생시킨 경우이지만 한 프레임에 여러 번을 호출한다면 패킷량은 더욱 늘어납니다. > 패킷 홍수는 싱글 플레이보다는 다수의 유저가 함께 플레이할 때 확인되는 경우가 많습니다. > 패킷 홍수의 대표적인 원인과 해결 방법은 다음과 같습니다. > * **TargetUserId를 사용하지 않은 경우** > * TargetUserId를 통해 특정 User에게만 함수를 호출하여 필요하지 않은 함수 호출을 줄입니다. > * 자세한 내용은 [Effective MSW 1](/docs/?postId=559) 가이드에서 "특정 클라이언트에만 응답 보내기" 내용을 참고해 봅시다. > * **클라이언트 값을 동기화 해야 하는 경우** > * 클라이언트 값을 서버를 통해 다른 유저들이나 다른 공간 함수 호출로 동기화해야하는 경우가 있습니다. > * 이때, 서버에서 동기화하기 보다는 Sync Property로 대체하거나, 한 Tick에 다른 클라이언트의 값들을 함께 모아서 한 번의 함수 호출로 전달해봅시다. 동기화 횟수를 줄이면 패킷 홍수 해결에 도움이 됩니다. 

### Memory

클라이언트에서 사용되는 메모리 사용량을 보여줍니다. 메모리 사용량이 너무 많아지지 않게 관리하는 것이 좋습니다. 특히 모바일 환경에서는 메모리 사용량이 1GB를 넘어가면 메이플스토리 월드가 강제 종료되는 문제가 발생할 수 있습니다.

### Entity

맵 별, UI 그룹 별 엔티티의 총 개수와 엔티티 생성 / 파괴 횟수를 보여줍니다. 엔티티의 생성 / 파괴가 자주 발생하면 전반적인 성능에 좋지 않습니다. 기기의 사양마다 다르지만 모바일 환경에서는 엔티티가 5000개 이상일 경우 성능 저하 현상이 발생할 수 있습니다. 그러므로 엔티티의 개수는 5000개 이하로 관리하는 것이 좋습니다.

[{"항목":"Total Entity","설명":"현재 월드에 생성된 모든 엔티티의 개수입니다. Client User Entity가 존재하는 맵 이외의 다른 맵은 불러오지 않습니다.Server 메이커에서 테스트 플레이를 할 때, User Entity가 한번이라도 이동했던 맵은 불러온 뒤 다시 파괴하지 않습니다. 실제 서버는 최초 실행 시 모든 맵의 엔티티를 불러옵니다."},{"항목":"Construct \/ Destroy Entity","설명":"엔티티가 생성 및 파괴된 개수를 보여줍니다.맵 단위로 엔티티가 이동하는 경우, 실제 엔티티가 생성 \/ 파괴되지 않더라도 개수를 세고 있습니다. 이는 향후 개선 예정입니다.이펙트, 파티클, 대미지 스킨의 파괴 또는 생성 횟수도 기록될 수 있으나 풀링(Pooling)되고 있기에 성능에 큰 영향을 미치지 않습니다."}]

> Tip. 풀링(Pooling)이란 오브젝트 풀링(Object Pooling)을 의미합니다. 오브젝트를 미리 생성해두고 재사용함으로써 성능을 향상시키는 방법을 말합니다.

##### 엔티티 관련 성능 저하 개선

엔티티로 인해 월드 성능이 저하될 경우 아래의 방법으로 개선할 수 있습니다.

  * 엔티티 개수가 많은 경우 클라이언트 측면에서 엔티티 개수가 너무 많으면 World FPS 뿐만 아니라 Engine FPS에도 악영향을 끼칠 수 있습니다. 만약 UI에 배치된 엔티티가 많다면 개별 UI 엔티티가 아니라 UI 그룹을 Disable 처리해 봅시다. Engine FPS 성능을 향상시킬 수 있습니다.

[{"index":"UI Entity Disable","0":"[png](16897413642185c6ae74a889e4a9e9a77f12573388e67)"},{"index":"UI Group Disable","0":"[png](168974137819127d563f222d94d33815194e818333c02)"}]

서버 측면에서 엔티티의 개수가 너무 많으면 Tick에 영향을 줄 수 있습니다. 또한 공개된 게임에서 서버를 새로 생성해야 하는 경우에는 초기화 과정이 오래 걸릴 수 있습니다. 엔티티의 개수를 줄이는 것이 가장 좋은 방법입니다.   


  * 엔티티 생성 / 파괴 횟수가 많은 경우 엔티티의 과도한 생성과 파괴는 월드 성능에 좋지 않은 영향을 미칩니다. 오브젝트 풀링을 통해 성능에 미치는 영향을 줄일 수 있습니다.




### Execute Space Count

다른 실행 공간의 함수를 호출하는 경우, 즉 클라이언트에서 서버 함수를 호출하거나 서버에서 클라이언트 함수를 호출하는 횟수를 보여줍니다.

[{"항목":"Send Count","설명":"다른 실행 공간의 함수 호출 송신 횟수입니다."},{"항목":"Receive Count","설명":"다른 실행 공간의 함수 호출 수신 횟수입니다."}]

##### Execute Space Count 관련 성능 저하 개선

Execute Space Count가 많아지면 FPS나 Tick에 악영향을 끼칠 수 있습니다. 시간이 오래 걸리는 함수를 과도하게 호출하지 않도록 수정해야 합니다. 특히 Execute Space Count가 많아지면 패킷 홍수가 발생하여 서버 단에서 패킷 밀림 현상이 생길 수 있으므로 주의해야 합니다.

### Execute Space Byte

다른 실행 공간의 함수를 호출할 때의 데이터량을 보여줍니다. 보통은 Execute Space Count에 비례하여 증가합니다. 하지만 클라이언트에서 Count는 낮은데 Byte만 높은 경우도 있습니다. 인터넷 회선이 불안정한 환경에서는 FPS가 높아도 움직임이 밀리거나 끊기는 듯한 모습을 볼 수 있습니다. 한 번에 전달되는 데이터의 크기와 전달 횟수를 줄이면 이러한 현상을 개선할 수 있습니다.

[{"항목":"Send Byte","설명":"다른 실행 공간의 함수 호출 송신 데이터량입니다."},{"항목":"Receive Byte","설명":"다른 실행 공간의 함수 호출 수신 데이터량입니다."}]

### Sync Property Count

Sync Property의 동기화 횟수입니다.

[{"항목":"Send Count","설명":"컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 송신 횟수입니다."},{"항목":"Receive Count","설명":"컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 수신 횟수입니다."}]

##### Sync Property Count 관련 성능 저하 개선

Sync Property Count가 많아지면 FPS나 Tick에 악영향을 끼칠 수 있습니다. Sync Property는 None-Sync Property와 달리 내부적으로 동기화 로직을 거칩니다. 너무 많은 Sync Property를 사용하면 월드 성능이 나빠질 수 있습니다. 그러므로 동기화가 필요하지 않은 프로퍼티는 None-Sync로 변경해야 합니다. 또한 모든 User에게 동기화할 필요가 없다면 다른 실행 공간 함수의 TargetUserId를 사용하여 동기화량을 줄일 수 있습니다.

### Sync Property Byte

Sync Property의 동기화 데이터량입니다.

[{"항목":"Send Byte","설명":"컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 송신 Byte입니다."},{"항목":"Receive Byte","설명":"컴포넌트 단위의 동기화 및 프로퍼티 별 동기화 수신 Byte입니다."}]

### TimerService

Timer Service를 이용한 타이머의 생성 / 파괴 정보입니다.

[{"항목":"Total Timer","설명":"현재 동작하거나 대기 중인 타이머 개수입니다."},{"항목":"Add Timer","설명":"생성된 타이머의 개수와 생성 위치를 보여줍니다. Effect Service를 사용하는 Effect 또한 내부적으로는 Timer를 사용하고 있기에 개수에 포함됩니다. 단, 호출 위치는 보이지 않습니다."},{"항목":"Remove Timer","설명":"삭제된 타이머의 개수입니다."}]

##### TimerService 관련 성능 저하 개선

Total Timer가 증가하고 계속 쌓이면 FPS나 Tick에 악영향을 끼칠 수 있습니다. 주로 타이머를 일시 정지한 뒤 제거하지 않았거나, 무한 반복되는 타이머를 생성한 뒤 제거하지 않았을 때 Total Timer가 증가합니다. 그러므로 isRepeat을 true로 설정한 `TimerService:SetTimer()` 함수를 사용하거나, `TimerService:SetTimerRepeat()` 함수로 생성된 타이머를 명시적으로 제거해야 합니다. Total Timer가 300개 이상이면 월드 성능이 저하될 수 있으므로 Timer 개수가 과도하게 늘어나지 않도록 관리해봅시다.

### Tween Logic

Tween Logic과 관련된 Tweener의 생성/파괴 정보입니다.

[{"항목":"Total Tween","설명":"현재 존재하는 Tweener 개수입니다."},{"항목":"Add Tween","설명":"생성된 Tweener 개수 및 생성 위치를 보여줍니다."},{"항목":"Remove Tween","설명":"삭제된 Tweener 개수입니다."}]

##### Tween Logic 관련 성능 저하 개선

Total Tween 개수가 증가하고 계속 쌓이면 FPS나 Tick에 악영향을 끼칠 수 있습니다. 이러한 문제는 Tweener의 AutoDestroy 프로퍼티 값을 false로 설정한 뒤 명시적으로 파괴해주지 않을 때 발생합니다. 그러므로 AutoDestroy를 false로 설정한 Tweener의 사용이 끝난 후에는 별도로 재사용하거나 파괴해야 합니다. Total Tween이 300 이상이면 화면 순간 끊김이나 FPS가 하락하는 등 월드 성능이 저하될 수 있으므로 Tweener 개수가 과도하게 늘어나지 않도록 관리해봅시다.