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]; } });
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% --
Running the code with different arguments yields different results. For example, try:
orperl test.pl 100:100
Update: Never mind, folks - it's just noise. Nothing to see here; move along.perl test.pl `perl -e 'print join(q[:], (1) x 200)'`
-- @/=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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |