|Perl: the Markov chain saw|
Re: Sprite animation with SDL_perlby CharlesClarkson (Curate)
|on May 05, 2002 at 17:17 UTC||Need Help??|
There is more to address here than algorithm efficiency. You need to learn more of perls' features. One glaring example is the lack of return values from subroutines. In perl subroutines can also be functons. Another example is the global variables defined at the beginning of the program. Globals are variables that are used anywhere in the program. They are usually frowned on. Let's take a look at one global: @fire_items. It is used exclusively in the subroutine: handle_fire().
handle_fire() is called each pass through the while block. The reason for making @fire_items global is because we don't want to lose the items between passes. The problem is if we want to use @fire_items in the future we need to take into account that at least one subroutine is changing it in an inobvious way. The use of many global variables makes it difficult to optimize and debug a program. There are too many dependencies.
When designing a subroutine, pretend a manager or teacher has assigned you the task. She has given the inputs, the outputs, and a few details. The rest of the program is not written yet or is not shown to you. Changing a variable in the program is not an option. Everything you need must be passed in and everthing you change must be passed back out. You can break the rules as you become a better programmer or as the situation dictates. While your learning, try to find a way to stick to them.
Here is the handle_fire() subroutine:
Three items initially caught my eye:
This is how handle_fire() is called:
Let's change handle_fire( $fire, $x, $y ) to accept and return a reference to @fire_items.
Let's keep $fire_items defined outside the while block to maintain it's value between passes. Remember $fire_items is a reference to @fire_items.
Here's our sub again (with some whitespace added).
In order to use $fire_items reference we'll need to de-reference it. We'll also need to add a return and change the line that receives the passed variables.
Now let's look at the data structure. By using an Array of Arrays, we can eliminate the joining and splitting of spaces from $x and $y.
The splice is removing something from the array and going to the next item. Since $fire_items is a reference, changing it changes an external variable. Something we normally want to avoid if possible. Also $skip is only used to get to the next index. First, we'll get rid of $skip. As far as I can tell splice always returns a value:
Now we'll add a temporary array to hold the values we're keeping and to avoid changing the $fire_items array. This is what I ended up with:
Since we are no longer using splice, we no longer need to track the index:
For speed you could forgo not changing $fire_items, but pushing is probably faster than splicing.HTH,
Charles K. Clarkson
Clarkson Energy Homes, Inc.