2011-03-08 83 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,这不是很棒,但它会快两倍。我不知道这个建议是否适用于你的光线投射(可能你真的需要从内部循环的同一个位置重新开始!),但这是一个在过去碰撞时帮助我的建议。