Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
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 chanting in the Monastery: (5)
As of 2015-07-04 19:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls