FAQ
Hello,

what is the most effecient way to combine multiple array refs into one array
ref, IE:

my $arrayrefA = ['1',2','3'];
my $arrayrefB = ['4','5','6'];
my $arrayrefC = ['7','8','9'];

my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)

TIA,

Mickalo

Search Discussions

  • John W. Krahn at Nov 11, 2005 at 5:18 pm

    Mike Blezien wrote:
    Hello, Hello,
    what is the most effecient way to combine multiple array refs into one
    array ref, IE:

    my $arrayrefA = ['1',2','3'];
    my $arrayrefB = ['4','5','6'];
    my $arrayrefC = ['7','8','9'];

    my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)
    So you just want to combine the contents of the anonymous arrays?

    my $allarrayref = [ @$arrayrefA, @$arrayrefB, @$arrayrefC ];


    John
    --
    use Perl;
    program
    fulfillment
  • Mike Blezien at Nov 11, 2005 at 6:42 pm
    Thanks John, this helps get me in the right direction of what I'm trying to
    accomplish :)

    Mickalo

    John W. Krahn wrote:
    Mike Blezien wrote:
    Hello,

    Hello,

    what is the most effecient way to combine multiple array refs into one
    array ref, IE:

    my $arrayrefA = ['1',2','3'];
    my $arrayrefB = ['4','5','6'];
    my $arrayrefC = ['7','8','9'];

    my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)

    So you just want to combine the contents of the anonymous arrays?

    my $allarrayref = [ @$arrayrefA, @$arrayrefB, @$arrayrefC ];


    John
  • Tom Allison at Nov 14, 2005 at 3:58 am

    John W. Krahn wrote:
    Mike Blezien wrote:
    Hello,

    Hello,

    what is the most effecient way to combine multiple array refs into one
    array ref, IE:

    my $arrayrefA = ['1',2','3'];
    my $arrayrefB = ['4','5','6'];
    my $arrayrefC = ['7','8','9'];

    my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)

    So you just want to combine the contents of the anonymous arrays?

    my $allarrayref = [ @$arrayrefA, @$arrayrefB, @$arrayrefC ];


    John
    You might want to Benchmark this.
    I know from the perl cookbook that joining two hashes can be done this
    way but it's also mentioned that it is very memory intensive. I don't
    know if the same applies here.

    My results show that this is not the best way to procede if you are
    interested in performance.

    use strict;
    use warnings;

    use Benchmark;
    use Time::HiRes;

    my $A = [1,2,3,4,5,6,7,8,9];
    my $B = [11,12,13,14,15,16,17,18,19];

    timethese(10000000,
    {
    'plain' => 'my $array = [$A, $B];',
    'loopy' => 'push @$A, $_ foreach @$B;'
    });

    Benchmark: timing 10000000 iterations of loopy, plain...
    loopy: 3 wallclock secs ( 4.69 usr + 0.00 sys = 4.69 CPU) @
    2132196.16/s (n=10000000)
    plain: 9 wallclock secs ( 8.94 usr + 0.00 sys = 8.94 CPU) @
    1118568.23/s (n=10000000)
  • John W. Krahn at Nov 14, 2005 at 9:18 am

    Tom Allison wrote:
    John W. Krahn wrote:
    Mike Blezien wrote:
    what is the most effecient way to combine multiple array refs into one
    array ref, IE:

    my $arrayrefA = ['1',2','3'];
    my $arrayrefB = ['4','5','6'];
    my $arrayrefC = ['7','8','9'];

    my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)
    So you just want to combine the contents of the anonymous arrays?

    my $allarrayref = [ @$arrayrefA, @$arrayrefB, @$arrayrefC ];
    You might want to Benchmark this.
    I know from the perl cookbook that joining two hashes can be done this
    way but it's also mentioned that it is very memory intensive. I don't
    know if the same applies here.

    My results show that this is not the best way to procede if you are
    interested in performance.

    use strict;
    use warnings;

    use Benchmark;
    use Time::HiRes;

    my $A = [1,2,3,4,5,6,7,8,9];
    my $B = [11,12,13,14,15,16,17,18,19];

    timethese(10000000,
    {
    'plain' => 'my $array = [$A, $B];',
    'loopy' => 'push @$A, $_ foreach @$B;'
    });
    Those aren't equivalent. 'plain' is only assigning two scalars while 'loopy'
    is pushing nine scalars.

    'plain' => 'my $array = [@$A, @$B];',
    'loopy' => 'push @$array, $_ foreach @$A, @$B;'

    But you don't need a foreach loop with push():

    'plain' => 'my $array = [@$A, @$B];',
    'loopy' => 'push @$array, @$A, @$B;'


    $ perl -e'
    use Benchmark q/cmpthese/;

    my $A = [ 1 .. 9 ];
    my $B = [ 11 .. 19 ];

    cmpthese ( 10_000_000, {
    scalar_assign => q/my $array = [ @$A, @$B ]/,
    array_assign => q/my $array; @$array = ( @$A, @$B )/,
    map_assign => q/my $array; @$array = map @$_, $A, $B/,
    push => q/my $array; push @$array, @$A, @$B/,
    push_loop1 => q/my $array; push @$array, $_ for @$A, @$B/,
    push_loop2 => q/my $array; push @$array, @$_ for $A, $B/,
    } );
    '
    Rate push_loop2 push_loop1 map_assign scalar_assign
    array_assign push
    push_loop2 550358/s -- -32% -49% -60%
    -69% -69%
    push_loop1 812348/s 48% -- -25% -40%
    -54% -55%
    map_assign 1084599/s 97% 34% -- -20%
    -38% -40%
    scalar_assign 1360544/s 147% 67% 25% --
    -23% -24%
    array_assign 1757469/s 219% 116% 62% 29%
    -- -2%
    push 1795332/s 226% 121% 66% 32%
    2% --




    John
    --
    use Perl;
    program
    fulfillment
  • Tom Allison at Nov 14, 2005 at 4:12 pm

    John W. Krahn wrote:
    Tom Allison wrote:
    John W. Krahn wrote:
    Mike Blezien wrote:

    what is the most effecient way to combine multiple array refs into one
    array ref, IE:

    my $arrayrefA = ['1',2','3'];
    my $arrayrefB = ['4','5','6'];
    my $arrayrefC = ['7','8','9'];

    my $allarrayref = (Combine $arrayrefA $arrayrefB $arrayrefC)
    So you just want to combine the contents of the anonymous arrays?

    my $allarrayref = [ @$arrayrefA, @$arrayrefB, @$arrayrefC ];
    You might want to Benchmark this.
    I know from the perl cookbook that joining two hashes can be done this
    way but it's also mentioned that it is very memory intensive. I don't
    know if the same applies here.

    My results show that this is not the best way to procede if you are
    interested in performance.

    use strict;
    use warnings;

    use Benchmark;
    use Time::HiRes;

    my $A = [1,2,3,4,5,6,7,8,9];
    my $B = [11,12,13,14,15,16,17,18,19];

    timethese(10000000,
    {
    'plain' => 'my $array = [$A, $B];',
    'loopy' => 'push @$A, $_ foreach @$B;'
    });

    Those aren't equivalent. 'plain' is only assigning two scalars while 'loopy'
    is pushing nine scalars.

    'plain' => 'my $array = [@$A, @$B];',
    'loopy' => 'push @$array, $_ foreach @$A, @$B;'

    But you don't need a foreach loop with push():

    'plain' => 'my $array = [@$A, @$B];',
    'loopy' => 'push @$array, @$A, @$B;'


    $ perl -e'
    use Benchmark q/cmpthese/;

    my $A = [ 1 .. 9 ];
    my $B = [ 11 .. 19 ];

    cmpthese ( 10_000_000, {
    scalar_assign => q/my $array = [ @$A, @$B ]/,
    array_assign => q/my $array; @$array = ( @$A, @$B )/,
    map_assign => q/my $array; @$array = map @$_, $A, $B/,
    push => q/my $array; push @$array, @$A, @$B/,
    push_loop1 => q/my $array; push @$array, $_ for @$A, @$B/,
    push_loop2 => q/my $array; push @$array, @$_ for $A, $B/,
    } );
    '
    Rate push_loop2 push_loop1 map_assign scalar_assign
    array_assign push
    push_loop2 550358/s -- -32% -49% -60%
    -69% -69%
    push_loop1 812348/s 48% -- -25% -40%
    -54% -55%
    map_assign 1084599/s 97% 34% -- -20%
    -38% -40%
    scalar_assign 1360544/s 147% 67% 25% --
    -23% -24%
    array_assign 1757469/s 219% 116% 62% 29%
    -- -2%
    push 1795332/s 226% 121% 66% 32%
    2% --




    John
    True dat.
    But you've shown even better what I was hinting at.
    The most "code efficient" method
    my $array = [ @$A, @$B ]
    is not the most efficient
    push @$array, @$_ for $A, $B
    that you presented.
  • Dave Gray at Nov 16, 2005 at 7:44 pm

    On 11/13/05, Tom Allison wrote:
    my $A = [1,2,3,4,5,6,7,8,9];
    my $B = [11,12,13,14,15,16,17,18,19];

    timethese(10000000,
    {
    'plain' => 'my $array = [$A, $B];',
    'loopy' => 'push @$A, $_ foreach @$B;'
    });
    Another important thing to notice is that John's benchmarks operate
    entirely on temporary variables while the ones above modify the main
    variables every single time, leading to a very large array in $A and
    most likely not demonstrating the specific performance measurement
    desired.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedNov 11, '05 at 5:03p
activeNov 16, '05 at 7:44p
posts7
users4
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase