The only difference between @ary1 and @ary2 is that the content of @ary2 was printed with print "@ary2\n" :)#!/usr/bin/perl use warnings; use strict; use Benchmark qw/:hireswallclock cmpthese/; my @ary = (0..5); my $len = $#ary; my @ary2 = @ary; print "ARRAY: @ary2\n"; # numbers -> strings #$_ += 0 foreach @ary2; # stings -> numbers #print "@ary\n"; cmpthese (-3, { 'intervals' => sub { foreach my $i (0..$len-1) { foreach my $j ($i+1..$len) { my @permuted = @ary[0..$i-1, $j, $i+1..$j-1, $i, $j+1. +.$len]; } } }, 'cross' => sub { foreach my $i (0..$len-1) { foreach my $j ($i+1..$len) { my @permuted = @ary; @permuted[$i, $j] = @permuted[$j, $i]; } } }, 'intervals2' => sub { foreach my $i (0..$len-1) { foreach my $j ($i+1..$len) { my @permuted = @ary2[0..$i-1, $j, $i+1..$j-1, $i, $j+1 +..$len]; } } }, 'cross2' => sub { foreach my $i (0..$len-1) { foreach my $j ($i+1..$len) { my @permuted = @ary2; @permuted[$i, $j] = @permuted[$j, $i]; } } }, });
Of course any comparison will show that these two arrays are equivalent. But internally they are stored in different ways, and it noticeably affects the performance:
Rate cross2 intervals2 intervals cross cross2 10490/s -- -2% -43% -55% intervals2 10742/s 2% -- -42% -54% intervals 18408/s 75% 71% -- -22% cross 23526/s 124% 119% 28% --
The performance loss is about 40 percent, and the faster way for permuting has lost its advantages—all because of string interpolation of array :)
Of course, the bigger is array, the worse is the effect — e.g. on array of 500 elements you will get smth like this:
s/iter intervals2 cross2 intervals cross intervals2 48.2 -- -20% -63% -81% cross2 38.6 25% -- -54% -77% intervals 17.8 171% 117% -- -49% cross 9.02 434% 328% 97% --
I cannot compare memory consumptions of of @ary and @ary2, but i think they will accord the performance loss :)
The conclusion after additional experiments is trivial — any treatment of the number as a string, even if the number is not modified, causes the number to be stored as string as a PVIV value which holds both a number and a string and needs much more memory (for further explanations see Perlguts illustrated) until you "numify" it (in my example you can uncomment the line next to print). And there ARE cases when it matters.
UPD: Conclusion updated according to diotalevi and Joost.
UPD2: The "numified" PVIV does not become IV, as you might think, but the string value stored in it is not further copied, and this causes a performance gain.
In reply to Don't treat your numbers as strings, or Interpolation is worse than you might think by Ieronim
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |