2015-02-08 37 views
2

我目前正在開發一個基本體素(立方體)遊戲引擎,而且我遇到了性能問題。遊戲中的每一幀:如何從TRY語句中避免糟糕的程序性能?

查找玩家的觀看方向→檢查玩家直觀視圖路徑中的每個座標→查找最近佔用的空間→在該塊周圍繪製線框。

我使用OpenTK,.NET/Mono(特別是C#)的OpenGL的綁定。我的代碼OnRenderFrame包含此:

try 
{ 
    for (int i = 0; i < 8; i++) 
    { 
     Vector3 block = InterfaceUtils.FindBlockLoc(Utilities.RoundToInt(cam.Position + (cam.lookat * i))); 
     if (block != Vector3.Zero) 
     { 
      // Draw the wireframe 
     } 
    } 
} 
catch 
{ 
} 

這段代碼的目的是從玩家檢查多達八塊,直到它找到一個塊。唯一的問題是try語句最常拋出一個(已處理的)異常:但是由此導致的滯後很大。當我觀察太空時,我只得到11FPS,但如果代碼成功,我得到50。

如果代碼是成功的(它可以繪製線框),我得到這個:

塊調查通過檢查的對象列表中,一個塊的工作位置。

public static Vector3 FindBlockLoc(Vector3 location) 
{ 
    Vector3 result = new Vector3(Vector3.Zero); 

    result = Deltashot.Game.objects.Find(v => v.Position == location).Position; 
    if (result != null) 
    { 
     return result; 
    } 
    else 
    { 
     return Vector3.Zero; 
    } 
} 

然而,這會返回一個NullReferenceException,我不得不使用try語句來得到它的運行。這又回到了一個...

+3

*爲什麼*你得到一個例外?不要只是捕捉和忽略它,你應該弄清楚爲什麼你首先得到一個例外。無論如何,它是什麼樣的例外? – 2015-02-08 19:50:25

+0

我的猜測nullref來自賦值結果,而不是存儲'find'的結果並測試其爲nullness – 2015-02-08 19:53:53

+1

這是什麼意思?「這將返回一個NullReferenceException?拋出的異常在哪裏?您做了什麼診斷?它是什麼?一個NullReferenceException幾乎總是需要避免的東西,而不是被捕獲的。 – 2015-02-08 20:10:02

回答

2

Throwing and catching Exceptions is a costly operation in C#,它似乎你使用exceptions as flow control

你應該避免NullReferenceException而不是每當它發生時捕捉它。

我猜例外發生在這裏:

result = Deltashot.Game.objects.Find(v => v.Position == location).Position; 

我建議是這樣的:

public static Vector3 FindBlockLoc(Vector3 location) 
{ 
    var result = Deltashot.Game.objects.Find(v => v.Position == location); 

    if (result != null && result.Position != null) 
    { 
     return result.Position; 
    } 
    else 
    { 
     return Vector3.Zero; 
    } 
} 
+0

謝謝!我編輯了函數和調用它的代碼,問題現在已經修復。 – 2015-02-08 20:15:16

0

如果改變這一行

result = Deltashot.Game.objects.Find(v => v.Position == location).Position; 

這樣:

result = Deltashot.Game.objects.Find(v => v.Position == location); 
if (result != null) 
{ 
    return result.Position; 
} 
... 

如果Find方法返回null,並且您嘗試訪問空結果中的任何成員,則可能會阻止該異常,您將得到一個空引用異常 - 您不應該在try/catch中包裝某些內容,花一點時間試圖弄清楚爲什麼你會得到例外。

一個簡單的方法是使用檢查分解點的所有代碼(直到找出發生錯誤的位置)因爲Deltashot.Game爲空或Deltashot.Game.objects爲空也是可能的。

public static Volume FindBlock(Vector3 location) 
{ 
    return Deltashot.Game.objects.Find(v => v.Position == location); 
} 

所以我返回整個卷對象(而不僅僅是位置):

0

我改變我的功能來修復這個問題。然後,我改變了,它叫這個代碼:

for (int i = 0; i < 8; i++) 
{ 
    var block = InterfaceUtils.FindBlock(Utilities.RoundToInt(cam.Position + (cam.lookat * i))); 
    if (block != null) 
    { 
     // Draw the wireframe 
    } 
} 

所以該塊最初無類型,並且它比作空的VAR的定義(不拋出異常!)

謝謝Juliano爲(類似的)解決方案和tophallen提供診斷建議。

相關問題