(I wish there were a synonym for array that began with "p")

In answering this node, I ran across the following odd performance behavior. I'd like someone who seriously understands perl internals to help me figure out what's going on.

The basic puzzle is this: it appears that I can construct two arrays which are identical and yet doing [0] on one array is much faster (by 10%) than doing [0] on the other. However, which array has faster access changes depending on which element I access and on some details of how the array is constructed.

So here's the code:

# This data format is related to the original problem # read this as "17 copies of 43", "33 copies of 21", etc. my $str = shift || "17:43:33:21:23:19:27:6"; my @a1 = (); my @a2 = (); my @a = split /:/, $str; while ( my ( $p, $ad ) = splice @a, 0, 2 ) { push @a1, map {$ad} (1..$p); push @a2, ($ad) x $p; } use Benchmark 'cmpthese'; print "Accessing element 0:\n"; cmpthese(-1, { made_by_map => sub { $a1[0]; }, made_by_x => sub { $a2[0]; } }); print "\nAccessing element 50:\n"; cmpthese(-1, { made_by_map => sub { $a1[50]; }, made_by_x => sub { $a2[50]; } }); print "\nAccessing element 99:\n"; cmpthese(-1, { made_by_map => sub { $a1[99]; }, made_by_x => sub { $a2[99]; } }); print "\nAccessing random element:\n"; cmpthese(-1, { made_by_map => sub { $a1[rand 100]; }, made_by_x => sub { $a2[rand 100]; } });
And here's the results of running that test code without any arguments:
Accessing element 0: Rate made_by_x made_by_map made_by_x 7554581/s -- -11% made_by_map 8479758/s 12% -- Accessing element 50: Rate made_by_x made_by_map made_by_x 7788171/s -- -4% made_by_map 8095273/s 4% -- Accessing element 99: Rate made_by_map made_by_x made_by_map 8058884/s -- -9% made_by_x 8882975/s 10% -- Accessing random element: Rate made_by_map made_by_x made_by_map 1724352/s -- -2% made_by_x 1758653/s 2% --
Now, if the performance figures were all within 1-2%, I might be able to dismiss the result as noise. But clearly, they aren't. They're large differences, and the results are consistent each time I run the code. (I'm using perl 5.8.2 as distributed with cygwin)

Running the code with different arguments yields different results. For example, try:

perl test.pl 100:100
or
perl test.pl `perl -e 'print join(q[:], (1) x 200)'`
Update: Never mind, folks - it's just noise. Nothing to see here; move along.
-- @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/

In reply to Perl array performance puzzle by fizbin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.