2013-12-16 74 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 

這就是爲什麼我想一些優化,如循環展開,但是,我不知道,如果它(我認爲沒有)與不定長循環(會導致編譯器不知道在編譯時的迴路長度)

綜上所述:

  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]); 
     } 
    } 

嵌套循環這樣的指示爲O(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)的複雜性)。顯然,你還需要小心,不要在數組邊界之外檢查,如果你的粒子大於單個像素,可能還有其他一些細節需要處理,但是你明白了。