开发者

How to speed up loops in ActionScript?

Hey guys,

I've开发者_StackOverflow社区 been writing a raycasting engine in ActionScript 3 and I've been getting some terrible performance.

At first I thought it was the obvious: raycasting is math intensive and I must be getting a low framerate because of the complex math involved however to my surprise this turned out to not be the case; it seems that the for-loop that draws the walls is the cause.

I tried experimenting with my code and I found that when I commented out the for-loop the FPS more then doubled but when I uncommented the for-loop but leaving the drawing code commented the FPS halved.

Is ActionScript really that slow that a simple loop by itself should eat up so much CPU time?

Thanks for any input!

Here is the code in question (Quck note: COLUMN_SIZE is just a constant defined as 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;

    }
}


decrementing while loops are said to be faster.

this changes depending on the player version, browser version, OS types and various parameters (type of the incremented object, break conditions .... ).

the fastest way to process lists of objects is to use a linked lists. I don't know if (and how) it applies here.

how long exactly is that y = yTop -> yBot loop?

no reason why it would lag so much, and anyway the good news is that your getTexturePixel() method is fast ^^

otherwise accessing values within an object is always slower than storing them locally

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

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

if these values are not updated during the Y loop, then storing them before the Y loop might be a good idea.


I have like three things that might help you out a little var x and y don't need to be declared up top don't know if you will get a performance boost for not referencing an existing portion of the memory so make your for loopsfor(var x:int = 0; x < COLUMN_SIZE; x++ ) { && for(var y:int = yTop; y< yBot; y++){ and also you are typecasting integers to integers for some reason var idx:int = (stage.stageWidth*y)+rx; hope these Ideas help you out at all. oh and a reference that might help you out. http://www.experts-exchange.com/Software/Photos_Graphics/Web_Graphics/Macromedia_Flash/ActionScript/A_2107-20-Tips-to-Optimize-your-ActionScript.html


My only specific advise is to make triple sure that you are not mixing ints and Numbers in comparison and math, make sure you are using locals as much as possible, and to try to avoid chasing object properties in inner loops.

These two documents will provide a little guidance on additional things you can try:

http://onflex.org/ACDS/AS3TuningInsideAVM2JIT.pdf

http://help.adobe.com/en_US/as3/mobile/flashplatform_optimizing_content.pdf


Why is the getTexturePixel(...) line even inside the inner loop?

If those values aren't changed, it should be called outside the loop, saved in a cache, and then the cached value should be saved to the array position.

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


It's hard to tell based solely on the code given but it looks like you've got possibly a On^2 algorithm going on there when you don't need one. Is it possible that you're testing 2x as many times as you need to be? Let me demonstrate what I mean...

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.
    }
}

Is it possible that instead you can do something like this?

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...
     }
}

That gives you On^1/2 instead of On^2, which isn't awesome but it's going to be 2x faster. I don't know if this advice is at all applicable to your raycasting (it's possible that you really do need to start over from the same spot on the inner loop!), but it's one that's helped me in the past with collisions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜