2013-12-16 3 views
2

XNA 게임을 만들고 있는데 일부 루프를 최적화하는 방법이 있는지 궁금합니다. 예를 들어 :XNA 최적화 - 루프 풀기?

나는() 난 그냥이 할 수있는 모든 타일 업데이트()

// Update method in Map Class 
    public void Update() 
    { 
     for (int index = 0; index < tiles.Count; index++) 
     { 
      tiles[index].Update(); 
     } 
    } 

이 잘 작동 전화를하지만지도 업데이트에 타일의 컬렉션을 포함하는지도 클래스를, 그래서 각 입자 검사를 ParticleManager 모든 입자에 대한 루프

// Update method in ParticleManager class 
    public void Update() 
    { 
     for (int index = 0; index < particle.Count; index++) 
     { 
      particle[index].Update(); 
     } 
    } 

    //Update Method in Particle class 
    public void Update() 
    { 
     for (int index = 0; index < Map.tiles.Count; index++) 
     { 
      CheckCollitions(Map.tile[index], this); 
     } 
    } 

을하고 그래서 모든 입자 (즉 입자의 컬렉션을 포함)을 ParticleManager 클래스와 관리, 입자 클래스처럼, 몇 가지 큰 인구 객체와 최악을 얻을 모든 타일에 대한 콜리 전. 계산의 는 20 개 입자 (100 개) 타일을 가지고한다면, 그것은 할 것 많은 :

나는 그것이 작동하는지 모르겠어요, 언 롤링 루프와 같은 일부 최적화 생각하지만 이유입니다
20 loops cycles * 100 loops cycles 

(I

  1. 그것은 수는 루프 언 롤링를 사용하는 루프를 최적화 : 정의되지 않은 길이 루프 (컴파일 시간에 그 루프 길이)

    는 정리해 모르는 컴파일러의 원인으로) 생각하지 않는다?

  2. 다른 유형의 최적화에 대해 조언을 해줄 수 있습니까?

감사

모든
+0

쿼드 트리의 혜택을 받으시겠습니까? 이러한 모든 충돌 검사는 일종의 필터로 피할 수 있습니다. – Magus

+0

구글 스페이스 분할 및 Magus 언급 쿼드 트리 – dferraro

답변

1

먼저, 루프 언 롤링은 마이크로 최적화하고 이익을 많이 얻을 수 없습니다. 절대적으로 필요한 때까지 귀찮게하지 마십시오.

더 중요한 것은 코드를 최적화하는 방법은 컬렉션을 반복하는 속도가 아니라 사용 된 데이터 구조와 알고리즘에 관한 것입니다. 특정 예에서

, 당신은 효과적으로을하고 있습니다 .. 중첩이 같은 루프

for (int p = 0; p < particle.Count; p++) 
    { 
     for (int t = 0; t < Map.tiles.Count; t++) 
     { 
       CheckCollitions(Map.tile[t], particle[p]); 
     } 
    } 

는 (N^2) 복잡성을 오 표시하고 잠재적 성능 문제의 확실한 표시이다.

일반적으로 충돌 감지로 작업 할 때 이미 알고있는 것을 기반으로 충돌 할 수있는 개체 수를 줄임으로써 코드를 최적화 할 수 있습니다.

예를 들어 타일이 움직이지 않고 일정한 격자에 배치되어 있다고 가정합니다. 나는 또한 입자가 아주 작다고 가정 할 수있다.

타일 데이터를 2 차원 배열로 저장한다고 가정 해 보겠습니다.

var tiles = new int[32,32]; 

값 0은 타일이 없음을 의미하고 값 1 (또는> 0)은 타일이 단단하다는 것을 의미합니다. 또한 화면에 타일을 렌더링 할 때 크기는 64x64 픽셀입니다.

즉, 간단한 수학을 사용하여 모든 타일과의 기본 충돌 테스트를 매우 빠르게 수행 할 수 있습니다.이때

for (int p = 0; p < particle.Count; p++) 
    { 
     var tileWidth = 64; 
     var tileHeight = 64; 
     var particlePosition = particle[p].Position; 
     var tx = particlePosition.X/tileWidth; 
     var ty = particlePosition.Y/tileHeight; 

     var tile = tiles[tx, ty]; 

     if(tile == 0) 
     { 
      // no collision 
     } 
     else 
     { 
      // collision detected 
     } 
    } 

, 당신은 입자 위치 빠진다 배열되는 타일 정확히 알고 (효율적으로 O (n)의 복잡도를 감소시키는) 내부 루프를 제거 하였다. 분명히 배열의 경계를 확인하지 않도록 조심해야 할 것입니다. 입자가 단일 픽셀보다 큰 경우 처리해야 할 다른 세부 정보가있을 수 있지만 아이디어를 얻으실 수 있습니다.