Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Stepping through an array

by rob_au (Abbot)
on Nov 22, 2002 at 10:28 UTC ( [id://215052]=CUFP: print w/replies, xml ) Need Help??

Following up from this thread and this post in particular, I decided to construct what I consider to be a fairly general solution to step through an array - The code below differs from some of the solutions in the referenced thread in that the array elements being stepped through do not necessarily need to be numeric, stepping based upon array index rather than array elements.

The syntax of this command is quite simply - step <step>, <array> - where <step> is the step value and <array> is the array to iterate through.

#!/usr/bin/perl -Tw use strict; sub step { my $step = shift; return map { $_[$_] } grep { $_ % $step == 0 } 0..$#_; } my @array = ( 'a' .. 'z' ); print join( ' ', step( 5, @array ) ), "\n";

Replies are listed 'Best First'.
Re: Stepping through an array
by Abigail-II (Bishop) on Nov 22, 2002 at 10:43 UTC
    sub step { my $step = shift; @_ [map {$_ * $step} 0 .. $#_ / $step]; }

    No grep needed. This should be more efficient with large step sizes.

    Abigail

      Abigail,
      I like your logic and agree it should be more efficient with large step sizes, but it doesn't appear to be faster. I've tried the following step sizes on an array of 1000000 elements: 5, 10, 100, 100, etc, 100000, 200000, 300000 & 500000. I bencmarked the results. The output I have included is with the step size of 500000 but is a fair summary of the results I saw:

      Benchmark: running Step 1, Step 2, Step 3 for at least 10 CPU seconds. +.. Step 1: 10 wallclock secs (10.47 usr + 0.02 sys = 10.49 CPU) @ 18 +5755.48/s (n=1948575) Step 2: 11 wallclock secs (10.48 usr + 0.02 sys = 10.50 CPU) @ 18 +7398.10/s (n=1967680) Step 3: 10 wallclock secs (10.01 usr + 0.00 sys = 10.01 CPU) @ 31 +5978.92/s (n=3162949)

      Here's the code:

      #!/usr/bin/perl -w use strict; use Benchmark; sub step1 { my $step = shift; @_[map {$_ * $step} 0..($#_ / $step)]; # curious what effect the bac +kets would have } sub step2 { my $step = shift; @_[map {$_ * $step} 0..$#_ / $step]; } sub step3 { my $step = shift; return map { $_[$_] } grep { $_ % $step == 0 } 0..$#_; } my @array = (0..1000000); timethese(-10, { 'Step 1' => 'step1(500000, @array)', 'Step 2' => 'step2(500000, @array)', 'Step 3' => 'step3(500000, @array)' });

      The only reason I post this is I'm curoius as to why what would appear to be a quicker and more effient piece of code is consistently the slowest (although not by much).

        But you are not measuring what you think you are! Once again, the high number of iterations per second Benchmark is reporting should ring many bells and whistles. Do you really think your computer is able to do more than 3 billion modulus operations per second? Because if you believe your Benchmark results, it's grepping through a 1000001 element array 315978.92 times a second. Of course it isn't. You have my @array, which makes that @array is only visible from the file. And not from an eval that's happening in Benchmark.pm (that would defeat all the purposes of my, wouldn't it?), Changing the last lines to:
        our @array = (0..1000000); timethese(-10, { 'Step 1' => 'step1(500000, @::array)', 'Step 2' => 'step2(500000, @::array)', 'Step 3' => 'step3(500000, @::array)' });

        we get far more sensible results:

        Benchmark: running Step 1, Step 2, Step 3 for at least 10 CPU seconds. +.. Step 1: 10 wallclock secs (10.17 usr + 0.00 sys = 10.17 CPU) @ 5.1 +1/s (n=52) Step 2: 10 wallclock secs (10.00 usr + 0.00 sys = 10.00 CPU) @ 5.1 +0/s (n=51) Step 3: 11 wallclock secs (10.72 usr + 0.00 sys = 10.72 CPU) @ 0.4 +7/s (n=5)

        Two things can be learned. First, don't blindly use my. Think whether it's appropriate. Second, always distrust your code if Benchmark returns many iterations per second - especially if you do lots of work during an iteration.

        Abigail

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://215052]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-25 22:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found