in reply to Re: How to speed up a nested loop?
in thread How to speed up a nested loop?

You can factor more work out of the inner loop, but I would expect the win to be very minor:
my $bxScaled = $bx * 16; my $byScaled = $by * 16; for my $x (0 .. 15) { my $xScaled = 16 * $x; # These calculations were factored out of the inner loop my $rx = $bxScaled + $x; my $tiles_for_rx = $tiles[$rx]; for my $y (0 .. 15) { # this calculates the tile index we are currently at, # using the x and y coords in this block my $tile_index = $y + $xScaled; # this calculates the real y value of this tile my $ry = $byScaled + $y; # insert type data into the internal map array and # note that there was change in this block if applicable my $tile = $tiles_for_rx->[$ry][$bz][type]; if (!defined $tile || $$tile != $type_data[$tile_index]) { $changed = 1; $$tile = $type_data[$tile_index]; } } }
Incidentally I'm puzzled at the array access of type. Should that be a $type? Or perhaps a hash access? Either way the current version looks like a bug.

Incidentally another cause of your win over the original is that you're using lexical variables consistently, which I believe are slightly faster than package variables.

Replies are listed 'Best First'.
Re^3: How to speed up a nested loop?
by GrandFather (Saint) on Sep 17, 2008 at 23:14 UTC

    I assumed type was a constant. It may be a transcription error of some sort. I can't see it making any difference to the results of refactoring however.

    Don't we always use lexical variables and strictures? ;) The OP may be interested in reading The strictures, according to Seuss.


    Perl reduces RSI - it saves typing
      I am using warnings and strict, as the link to the .pl file in the op shows. Explanation as to what's going on with that though is below. :)
Re^3: How to speed up a nested loop?
by Xenofur (Monk) on Sep 18, 2008 at 08:26 UTC
    Your hint has some truth. I should probably refactor my tiles array so i can get a reference to $tiles$bz$rx and go on from there. However you should probably read up about references a bit, as your code would never work as it is there. :) As for type, that is indeed a constant. Hashes are too slow, thus i used constants to build pseudo-hashes.
      What are you talking about? If Grandfather's code works, then my code should work as well because it is just a trivial refactoring. If it does not work, then I guarantee that it is the result of a silly typo and not a result of my not understanding how to use references in Perl. If I've done something you don't understand, the odds are higher that I understand something about references in Perl that you don't, than the reverse.

      If you doubt my competence, I suggest that you browse 10 or 20 of my best nodes. (You might want to skip the first couple, at least half of the top 10 don't have real programming meat.)

      On using type as a constant, the usual convention is that constants should be ALL_CAPS. It doesn't matter to Perl, but you are violating expectations there.

        What i don't understand in your code is what the purpose of this is meant to be:
        my $tiles_for_rx = $tiles[$rx];
        My understanding is that this dumps the size of $tiles[$rx] in $tiles_for_rx, due to being a multi-dimensional array. I may be wrong there, but the debugger seems to agree.

        However my understanding or lack of is not the point here. The point is that your variant did not work in the live when applied to my code. This works: When i try to refactor it to look like your example, it doesn't. Now mind you, i may be making some kind of mistake somewhere, but i'm fairly sure that your variant can't work. Feel free to correct me if i am making a mistake.