in reply to Re: Re^2: How to connect more arrays to a new array
in thread Find unique elements from multiple arrays

You can speed up even more and make it strict safe by replacing local with my.

Unfortunately in Perl 5.6.1 it seems that keys comes off in a different order for lexical and global hashes (with anonymous hashes coming off in the same order as global).

  • Comment on Re: Re: Re^2: How to connect more arrays to a new array

Replies are listed 'Best First'.
Re: How to connect more arrays to a new array
by Abigail-II (Bishop) on Apr 28, 2003 at 12:50 UTC
    Unfortunately in Perl 5.6.1 it seems that keys comes off in a different order for lexical and global hashes

    That's an interesting and unexpected observation. Do you have an example?

    Abigail

      Anonymonks observation is both strange and true. The following shows the results from AS 5.6.1 and 5.8 with ari/buk using an our'd hash and buk2 using a my'd hash.

      #! perl -slw use strict; use vars qw[@a @b @c @d]; use Benchmark 'cmpthese'; our @a=1..10; our @b=5..15; our @c=10..20; our @d=15..25; our (@A, @B, @C); my $ari = '@A = keys %{{ map +($_ => undef), @a, @b, @c, @d }};'; my $buk = '@B = do{local %h; ++@h{@a,@b,@c,@d}; keys %h};'; my $buk2= '@C = do{ my %h; ++@h{@a,@b,@c,@d}; keys %h};'; cmpthese( -1, { ari=>$ari, buk=>$buk, buk2=>$buk2 }); print "@A\n@B\n@C"; __END__ C:\test>junk Benchmark: running ari, buk, buk2, each for at least 1 CPU seconds ... ari: 1 wallclock secs ( 1.07 usr + 0.00 sys = 1.07 CPU) @ 12 +52.80/s (n=1343) buk: 1 wallclock secs ( 1.16 usr + 0.00 sys = 1.16 CPU) @ 23 +12.39/s (n=2687) buk2: 1 wallclock secs ( 1.09 usr + 0.00 sys = 1.09 CPU) @ 24 +62.88/s (n=2687) Rate ari buk buk2 ari 1253/s -- -46% -49% buk 2312/s 85% -- -6% buk2 2463/s 97% 7% -- 1 2 3 4 10 5 11 20 6 12 21 7 13 22 8 14 23 9 15 24 16 25 17 18 19 1 2 3 4 10 5 11 20 6 12 21 7 13 22 8 14 23 9 15 24 16 25 17 18 19 1 2 3 10 4 11 5 20 12 6 21 13 7 22 14 8 23 15 9 24 16 25 17 18 19 C:\test>perl58 junk.pl Rate ari buk buk2 ari 744/s -- -41% -43% buk 1265/s 70% -- -3% buk2 1307/s 76% 3% -- 11 21 7 17 2 22 1 18 23 16 13 25 6 3 9 12 20 14 15 8 4 24 19 10 5 11 21 7 17 2 22 1 18 23 16 13 25 6 3 9 12 20 14 15 8 4 24 19 10 5 11 21 7 17 2 22 1 18 23 16 13 25 6 3 9 12 20 15 14 8 4 24 19 10 5

      Even more surprising from my point of view is how much slower 5.8 is compared 5.6.1?

      Examine what is said, not who speaks.
      1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
      2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
      3) Any sufficiently advanced technology is indistinguishable from magic.
      Arthur C. Clarke.
        Cute. It starts happening in 5.005_52, and ceases to happen in 5.7.1. And it only happens if you run the "my %h" at least twice, otherwise, it returns the same as the localized version.

        My guess is that it is related to Perl not completely throwing away a lexical variable if it goes out of scope, because you often reenter a block and it's faster to keep the structure around. Look at this:

        my @a = 1 .. 10; my @b = 5 .. 15; my @c = 10 .. 20; my @d = 15 .. 25; for (1 .. 2) { @B = do {local %h; $h {$a [0]} ++; print "B: ", scalar %h, "\n"; ++@h {@a, @b, @c, @d}; keys %h}; @C = do { my %h; $h {$a [0]} ++; print "C: ", scalar %h, "\n"; ++@h {@a, @b, @c, @d}; keys %h}; } __END__ B: 1/8 C: 1/8 B: 1/8 C: 1/32

        The second time it's executing the my %h block, the hash already has 32 buckets.

        Abigail