Unity Performance Testing — 자동화 성능 검증
Unity Performance Testing 패키지(com.unity.test-framework.performance)는 Unity Test Framework 위에서 동작하는 성능 벤치마크 도구입니다. 프레임 시간, 메모리, GC 할당을 자동 측정하고 결과를 JSON으로 저장해 CI 파이프라인에서 성능 회귀를 감지할 수 있습니다.
1. 패키지 설치 및 설정
섹션 제목: “1. 패키지 설치 및 설정”{ "dependencies": { "com.unity.test-framework": "1.3.9", "com.unity.test-framework.performance": "3.0.3" }}// Assembly Definition — Tests 어셈블리에 추가2. 기본 성능 테스트
섹션 제목: “2. 기본 성능 테스트”using NUnit.Framework;using Unity.PerformanceTesting;using UnityEngine;using UnityEngine.TestTools;using System.Collections;
public class BasicPerformanceTests{ // 동기 메서드 측정 [Test, Performance] public void MathOperations_Performance() { Measure.Method(() => { float result = 0f; for (int i = 0; i < 10000; i++) result += Mathf.Sqrt(i); }) .WarmupCount(5) .MeasurementCount(20) .IterationsPerMeasurement(1) .GC() // GC 할당도 측정 .Run(); }
// 비동기/코루틴 측정 [UnityTest, Performance] public IEnumerator SceneLoad_Performance() { using (Measure.Frames().Scope()) { yield return SceneManager.LoadSceneAsync("GameScene"); } // Scope 내 모든 프레임의 시간을 수집 }}3. SampleGroup — 커스텀 측정
섹션 제목: “3. SampleGroup — 커스텀 측정”[Test, Performance]public void ECS_Query_Performance(){ // 커스텀 SampleGroup 정의 var queryTime = new SampleGroup( "ECS Query Time", SampleUnit.Millisecond, increaseIsBetter: false);
var entityCount = new SampleGroup( "Entity Count", SampleUnit.None, increaseIsBetter: true);
Measure.Method(() => { var sw = System.Diagnostics.Stopwatch.StartNew(); int count = RunECSQuery(); sw.Stop();
Measure.Custom(queryTime, sw.Elapsed.TotalMilliseconds); Measure.Custom(entityCount, count); }) .WarmupCount(3) .MeasurementCount(15) .Run();}4. 프레임 시간 측정
섹션 제목: “4. 프레임 시간 측정”[UnityTest, Performance]public IEnumerator GameplayLoop_FrameTime(){ // 씬 로드 yield return SceneManager.LoadSceneAsync("BattleScene");
// 설정 단계 (측정 제외) SpawnEnemies(100); yield return new WaitForSeconds(1f);
// 60프레임 측정 yield return Measure.Frames() .WarmupCount(10) .MeasurementCount(60) .SampleGroup(new SampleGroup( "Frame Time", SampleUnit.Millisecond)) .Run();}
// 특정 구간만 측정[UnityTest, Performance]public IEnumerator ExplosionEffect_Performance(){ yield return SceneManager.LoadSceneAsync("TestScene");
using (Measure.Frames() .SampleGroup("Explosion Frame Time") .Scope()) { TriggerExplosion(); yield return new WaitForSeconds(2f); }}5. 메모리 측정
섹션 제목: “5. 메모리 측정”[Test, Performance]public void ObjectPool_Memory(){ // 메모리 할당량 측정 Measure.Method(() => { var pool = new List<GameObject>(); for (int i = 0; i < 100; i++) pool.Add(new GameObject());
foreach (var go in pool) Object.DestroyImmediate(go); }) .GC() // GC.Collect() 호출 및 할당 추적 .MeasurementCount(10) .Run();
// SampleGroup으로 메모리 직접 샘플링 var memGroup = new SampleGroup( "Total Memory MB", SampleUnit.Megabyte);
Measure.Custom(memGroup, GC.GetTotalMemory(false) / (1024f * 1024f));}6. CI 연동 — 결과 비교
섹션 제목: “6. CI 연동 — 결과 비교”# 테스트 실행 및 JSON 결과 저장Unity -batchmode -projectPath . \ -runTests \ -testPlatform EditMode \ -testResults results.xml \ -performanceTestResults perf_results.json
# 결과 파일 위치# Assets/StreamingAssets/PerformanceTest*.json// 결과 JSON 구조// {// "results": [{// "name": "MathOperations_Performance",// "sampleGroups": [{// "name": "Time",// "unit": "Millisecond",// "samples": [0.12, 0.11, 0.13, ...],// "median": 0.12,// "average": 0.12,// "standardDeviation": 0.005// }]// }]// }7. 성능 회귀 감지 패턴
섹션 제목: “7. 성능 회귀 감지 패턴”// 임계값 기반 회귀 감지[Test, Performance]public void Pathfinding_Performance_Threshold(){ float totalTime = 0f; const int runs = 50;
Measure.Method(() => { var sw = System.Diagnostics.Stopwatch.StartNew(); RunPathfinding(); totalTime += (float)sw.Elapsed.TotalMilliseconds; }) .MeasurementCount(runs) .Run();
float avg = totalTime / runs;
// 5ms 초과 시 실패 Assert.Less(avg, 5f, $"경로 탐색 평균 시간이 임계값 초과: {avg:F2}ms");}Unity Performance Testing은 Measure.Method로 CPU 코드를, Measure.Frames로 렌더링 성능을 측정하세요. .GC()를 항상 포함해 GC 할당 제로화(zero-alloc) 목표를 수치로 검증하고, JSON 결과를 CI에서 이전 빌드와 비교해 성능 회귀를 자동으로 감지하는 파이프라인을 구축하면 게임 최적화 작업이 훨씬 체계적으로 진행됩니다.