2011-03-08 27 views
0

嘿傢伙,
我一直在ActionScript 3中編寫一個光線投射引擎,我一直在得到一些糟糕的表現。
起初我認爲這是顯而易見的:光線投射是數學密集型的,因爲涉及複雜的數學運算,我必須得到較低的幀速率,但是令我驚訝的是,事實證明情況並非如此;看起來,繪製牆壁的for-loop是原因。

我試着用我的代碼進行試驗,發現當我註釋掉for循環時,FPS更加加倍,但是當我取消註釋for循環但留下圖形代碼評論FPS減半時。
ActionScript是否真的很慢,簡單的循環本身應該消耗太多的CPU時間?如何加快ActionScript中的循環?

感謝您的任何意見!

這裏是有問題的代碼(Quck注:COLUMN_SIZE只是定義爲1的常數):

var y:int = 0; 
var x:int = 0; 
var rx:int = 0; 

for(x = 0; x < COLUMN_SIZE; x++) { 

    yt = ys; 
    rx = x + sx; 
    for(y = yTop; y < yBot; y++) { 

     var idx:int = int((stage.stageWidth*y)+rx); 

     pBuffer[idx] = getTexturePixel(ray.tile-1, ray.texel, int(yt), ray.horz); 
     yt += yi; 

    } 
} 
+0

什麼是其餘的類型(yt,rx,yTop,yBot等)? – mpdonadio 2011-03-08 20:06:57

+0

@MPD這更多的是關於循環本身。速度大大減慢,甚至如果我註釋掉與getTexturePixel行了,但這裏的功能是:'函數getTexturePixel(索引:INT,X:INT,Y:INT,陰影:布爾= FALSE):UINT { \t \t var clr:uint; \t \t 如果(指數> = 0 &&指數 JamesK89 2011-03-08 20:24:48

+0

這並沒有真正回答我的問題。循環/代碼中其他變量的類型是什麼?混合整數和數字可能會導致性能問題。 – mpdonadio 2011-03-08 20:30:11

回答

3

遞減while循環被認爲是快。

根據播放器版本,瀏覽器版本,操作系統類型和各種參數(增加對象的類型,中斷條件....),此更改。

處理對象列表的最快方法是使用鏈接列表。我不知道它是否(以及如何)適用於此。

究竟是多久y = yTop - > yBot循環?

沒有理由爲什麼它會落後這麼多了,反正好消息是,你getTexturePixel()方法是快速的^^

對象中,否則訪問值始終不是將它們存儲在本地

stage.stageWidth//won't change during the loops :) 

//and maybe also 
ray.tile-1, ray.texel, int(yt), ray.horz 

如果這些值在Y循環期間沒有更新,那麼將它們存儲在Y循環之前可能是一個好主意。

+0

yTop-yBot循環取決於舞臺尺寸,但平均而言,它不會大於垂直舞臺尺寸的一半。我注意到,循環本身似乎比我發現bizzare的像素的實際設置/獲取要慢。另外我使用的是Flash 10.1(Flash Professional CS5),ActionScript 3和Firefox 3.16。 – JamesK89 2011-03-08 20:26:09

+0

我發現將stage.stageWidth/Height放入腳本頂部的一個常量並使用它可以顯着提高性能。在進入循環之前將ray.tile等變量放入變量似乎也有所幫助。 – JamesK89 2011-03-08 21:13:33

+0

:)另一件好事是宣佈你的ray類最終,並且,再次,你可以通過使用鏈表真正提高整體表現。檢查這個例如:http://pixelero.wordpress.com/2009/06/11/linkedgrid/ – nicoptere 2011-03-09 00:18:37

0

爲什麼getTexturePixel(...)行甚至在內部循環中?

如果這些值沒有改變,應該在循環外調用,保存在緩存中,然後緩存值應該保存到數組位置。

cachedPixel = getTexturePixel(ray.tile-1, ray.texel, int(yt), ray.horz); 

    for(y = yTop; y < yBot; y++) 
    { 
     var idx:int = int((stage.stageWidth*y)+rx); 

     pBuffer[idx] = cachedPixel; 
     yt += yi; 
    } 
1

我有這樣三件事情可以幫助你出一點 變種x和y無需聲明向上頂不知道你會得到一個性能提升不引用現有部分的內存,所以使你的循環for(var x:int = 0; x < COLUMN_SIZE; x++) { & & for(var y:int = yTop; y< yBot; y++){而且你也是由於某種原因typecasting整數整數var idx:int = (stage.stageWidth*y)+rx;希望這些想法可以幫助你。哦,並可以幫助你的參考。 http://www.experts-exchange.com/Software/Photos_Graphics/Web_Graphics/Macromedia_Flash/ActionScript/A_2107-20-Tips-to-Optimize-your-ActionScript.html

+1

,並使第一次循環遞減將爲 '爲(var x:int = COLUMN_SIZE-1; x> = 0; X - ){' – nhutto 2011-03-08 20:51:51

0

很難僅僅根據給出的代碼告訴,但它看起來就像你當你不需要時,可能會有一個On^2算法。你是否有可能多次測試2x次數?讓我來證明我的意思...

for(var i:int = 0 ; i < 1000 ; i++){ 
    for(var j:int = 0 ; j < 1000 ; j++){ 
     // This can be pretty wasteful in certain situations... 
     // for example, if you're collision detecting between 
     // all objects on a field, you are performing twice the 
     // comparisons you need to when you start j over at 0 
     // every time. 
    } 
} 

是否有可能您可以這樣做?

for(var i:int = 0 ; i < 1000 ; i++){ 
    for(var j:int = i + 1 ; j < 1000 ; j++){ 
     // Now you won't compare the same two values more than once... 
    } 
} 

這給你的^ 1/2而不是^ 2,這不是很棒,但它會快兩倍。我不知道這個建議是否適用於你的光線投射(可能你真的需要從內部循環的同一個位置重新開始!),但這是一個在過去碰撞時幫助我的建議。