Wait a minute with setTimeout (1)

, under actionscript, Code snippets.

While working on a game, I created a function spawner. The idea was to make a function which would call a function like createEnemy() a hundred times with an interval. So I quickly created a static function. Yes, I could use Chain, but this function was created in a minute and I haven’t thought of that class.

[as]
public static function create(total:int, interval:int, func:Function, delay:int = 0):void
{
for (var i:int; i < total; ++i) { setTimeout(func, delay + interval * i); } } [/as] This function is easy to understand. Maybe it's not needed as a new class, but it could be handy in a game. By the way; I use setTimeout a lot, it’s sometimes easier than the Timer class. You could call the function like this (if it is placed in a class called Spawner):
[as]
Spawner.create(1000, 1000, createEnemy);
// a new enemy should be created after a second, a thousand times
[/as]
While profiling this peace of code I found it is a bit intensive and could be optimized very simple.

So, what is the problem? This profiler shows the memory usage of a empty flash calling the example Spawner.create function:

I have used FlashPlayer 10.1 (release) and the FlashDevelop for profiling.

See the column ‘count’, which represents the current count of objects. For some reason there are a lot of ‘Functions’ (2000?). There are also 1000x ‘Array’ and ‘SetIntervalTimer’. Now I don’t know what that exactly means, but it is a lot, right? I haven’t used Arrays yet, so setTimeout must be using arrays internally. I think because the intervals are created inside a loop, they are already instantiated and there must be some references to objects too. Inside this test, the createEnemy function is empty, so it is a bit unexpected what happens here.

So I tried to rewrite the code a bit to see if it makes a difference if they are not instantiated at the same time, but create a new interval after one time-out has been called (after each other). It is not very hard to do, so here it is:
[as]
public static function create(total:int, interval:int, func:Function, delay:int = 0):void
{
setTimeout(createNext, delay, total – 1, interval, func, delay);
}

private static function createNext(total:int, interval:int, func:Function, delay:int):void
{
if (func != null)
{
func();
if (total > 0)
setTimeout(createNext, interval, total – 1, interval, func, delay);
}
}

[/as]
The Spawner.create works the same as before, only it is not creating all intervals inside a loop, but passes a reference to the function to the new timeout. Now take a look at the profiler again:

There are less ‘Functions’ and only 11 ‘SetIntervalTimer’, which could be considered as better. Conclusion: If you are using [i]setTimeout[/i], you should be aware how to use it and check if you could improve it in your own app/game.

Just one response to “Wait a minute with setTimeout”

  1. infixed says:

    to bookmarks in my head…

Say something interesting

Please link to code from an external resource, like gist.github.com.