Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Generating an array of n identical elements

by bronto (Priest)
on Sep 16, 2002 at 08:42 UTC ( #198184=snippet: print w/ replies, xml ) Need Help??

Description:

You are an old Matlab(TM) user, aren't you? Now your boss asked you to learn perl and you really miss the dear old ones function. You were used to create n-lenght arrays -er... vectors!- of identical elements by simply doing

fives = 5*ones(1:20) ;

and now in perl you don't find any ones.

Stop crying and use map!

# An array of twenty fives:
my @fives = map 5,(1..20) ;

# An array of 3 Xes
# (You must be at least 18 to watch this!)
my @porn = map 'X',(1..3) ;

my @whatever = replicate($x,$n) ;

sub replicate {
  my ($x,$n) = @_ ;

  return () if $n < 1 ;

  return map $x,(1..$n) ;
}
Comment on Generating an array of n identical elements
Download Code
Re: Generating an array of n identical elements
by blakem (Monsignor) on Sep 16, 2002 at 08:50 UTC

      WOW! Good point, Blake!

      Does anyone have any benchmark of the two solutions?

      Ciao!
      --bronto

      # Another Perl edition of a song:
      # The End, by The Beatles
      END {
        $you->take($love) eq $you->made($love) ;
      }

        Not certain that its exactly a great Benchmark, but it seems to clearly indicates that using the x op is substantially faster.

        #! perl -sw use strict; use Benchmark qw(cmpthese); sub mapgen { return map $_[0], (1..$_[1]); } sub xgen { return ($_[0]) x $_[1]; } cmpthese( 1000, { mapgen => 'my @ones = mapgen 1, 1000;', xgen => 'my @ones = xgen 1, 1000;', }); __END__ Benchmark: timing 1000 iterations of mapgen, xgen... mapgen: 9 wallclock secs ( 8.18 usr + 0.00 sys = 8.18 CPU) @ 12 +2.23/s (n=1000) xgen: 5 wallclock secs ( 5.15 usr + 0.00 sys = 5.15 CPU) @ 19 +4.29/s (n=1000) Rate mapgen xgen mapgen 122/s -- -37% xgen 194/s 59% -- C:\test>

        Well It's better than the Abottoire, but Yorkshire!
        One for largish and one for small lists:
        $ perl -MBenchmark -e'timethese(10000, { map => sub { @_ = map 1, 1..1 +000 }, x => sub { @_ = (1)x1000 }})' Benchmark: timing 10000 iterations of map, x... map: 29 wallclock secs (27.09 usr + 0.24 sys = 27.33 CPU) @ 36 +5.90/s (n=10000) x: 14 wallclock secs (13.36 usr + 0.09 sys = 13.45 CPU) @ 74 +3.49/s (n=10000) $ perl -MBenchmark -e'timethese(1000000, { map => sub { @_ = map 1, 1. +.5 }, x => sub { @_ = (1)x5 }})' Benchmark: timing 1000000 iterations of map, x... map: 17 wallclock secs (15.55 usr + 0.15 sys = 15.70 CPU) @ 63 +694.27/s (n=1000000) x: 9 wallclock secs ( 8.44 usr + 0.11 sys = 8.55 CPU) @ 11 +6959.06/s (n=1000000)
        The message is clear - a pretty precise 100% speed benefit from x. Of note is what happens internally:
        $ perl -MO=Deparse,-x7 -e'timethese(1000000, { map => sub { @_ = map 1 +, 1..5 }, x => sub { @_ = (1)x5 }})' timethese 1000000, {'map', sub { @_ = map(1, (1, 2, 3, 4, 5)); } , 'x', sub { @_ = (1) x 5; } }; -e syntax OK
        I'll spare you the corresponding output from 1..1000 - a list of 1000 numeric literals. In other words not only does the map take twice as long in every instance, it also consumes more memory - grossly so, for large lists.

        Makeshifts last the longest.

Re: Generating an array of n identical elements
by Aristotle (Chancellor) on Sep 16, 2002 at 09:23 UTC

Back to Snippets Section

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2014-07-13 08:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (248 votes), past polls