TATMWTDI*
Nobody mentioned concatenation operator, so I had to test it, but it turns out
it's about the same speed as embedding variables in a string. I'm surprised
that using two variables (rassign2var) is faster than using one variable
(rassign) since you would think perl would have an easier time optimizing the
one variable by just using an internal second variable. Maybe it's
prioritizing memory footprint over cpu usage.
Of course, the real winner is just to append to the string instead of the
beginning, but sometimes that's just not feasible. The strange (i.e., cool but
unexpected) thing about this is that after appending, it optimizes the
variables so everything works faster. I had to rewrite the benchmark tests to
use a random string each iteration otherwise the numbers were thrown off. I
illustrate this in my two timings at the bottom which should be identical, but
the wtf() function throws them off balance.
(hoping my formatting makes it through the listserve)
<Illian[4984]~> ~/bin/benchmarkexample.pl
Rate rsubstr3arg rsprintf rassign rpack rconcat rpackfixed
rassign2var rconcat2var rjoin rjoinnosep rsubstr4arg rassignrev rconcatrev1
rconcatrev
rsubstr3arg 575136/s -- -12% -15% -15% -16% -17%
-21% -21% -22% -22% -31% -37% -37%
-37%
rsprintf 656472/s 14% -- -3% -3% -5% -5%
-10% -10% -11% -11% -22% -28% -28%
-28%
rassign 678422/s 18% 3% -- -0% -1% -2%
-7% -7% -8% -8% -19% -25% -25%
-26%
rpack 680090/s 18% 4% 0% -- -1% -2%
-7% -7% -8% -8% -19% -25% -25%
-26%
rconcat 688124/s 20% 5% 1% 1% -- -0%
-6% -6% -7% -7% -18% -24% -24%
-25%
rpackfixed 691222/s 20% 5% 2% 2% 0% --
-6% -6% -6% -7% -17% -24% -24%
-24%
rassign2var 732361/s 27% 12% 8% 8% 6% 6%
-- -0% -1% -1% -13% -19% -20%
-20%
rconcat2var 732633/s 27% 12% 8% 8% 6% 6%
0% -- -0% -1% -13% -19% -20%
-20%
rjoin 736109/s 28% 12% 9% 8% 7% 6%
1% 0% -- -0% -12% -19% -19%
-20%
rjoinnosep 739485/s 29% 13% 9% 9% 7% 7%
1% 1% 0% -- -12% -18% -19%
-19%
rsubstr4arg 837717/s 46% 28% 23% 23% 22% 21%
14% 14% 14% 13% -- -8% -8%
-8%
rassignrev 906027/s 58% 38% 34% 33% 32% 31%
24% 24% 23% 23% 8% -- -0%
-1%
rconcatrev1 910222/s 58% 39% 34% 34% 32% 32%
24% 24% 24% 23% 9% 0% --
-1%
rconcatrev 915465/s 59% 39% 35% 35% 33% 32%
25% 25% 24% 24% 9% 1% 1%
--
Benchmark: running fassign for at least 2 CPU seconds...
fassign: 2.01368 wallclock secs ( 2.01 usr + 0.00 sys = 2.01 CPU) @
739648.26/s (n=1486693)
Benchmark: running fassign for at least 2 CPU seconds...
fassign: 2.00891 wallclock secs ( 2.01 usr + 0.00 sys = 2.01 CPU) @
2918546.77/s (n=5866279)
<Illian[4985]~> cat ~/bin/benchmarkexample.pl
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;
use Benchmark qw( timethese cmpthese :hireswallclock);
my $var1=rand();
my $var2=rand();
my $count = shift || -2;
cmpthese ( $count , {
# fassign => sub { my $x = $var1 ; $x = "$var2$x" },
## fassignrev => sub { my $x = $var2 ; $x = "$x$var1" },
# fassign2var => sub { my $x = $var1 ; my $y = "$var2$x"; $x=$y },
# fsubstr4arg => sub { my $x = $var1 ; substr( $x, 0, 0, $var2) ; $x},
# fsubstr3arg => sub { my $x = $var1 ; substr( $x, 0, 0) = $var2 ; $x},
# fconcat => sub { my $x = $var1 ; $x = $var2 . $x },
## fconcatrev => sub { my $x = $var2 ; $x .= $var1 },
# fconcat2var => sub { my $x = $var1 ; my $y = $var2 . $x; $x=$y },
# fpack => sub { my $x = $var1 ; $x = pack('a*a*',$var2,$x) },
# fpackfixed => sub { my $x = $var1 ; $x = pack('a17a*',$var2,$x) },
# fjoin => sub { my $x = $var1 ; $x = join ('/',$var2, $x ) },
# fjoinnosep => sub { my $x = $var1 ; $x = join ('', $var2, $x ) },
# fsprintf => sub { my $x = $var1 ; $x = sprintf('%s%s',$var2,$x) },
rassign => sub { my $x = rand() ; $x = "$var2$x" },
rassignrev => sub { my $x = rand() ; $x = "$x$var2" },
rassign2var => sub { my $x = rand() ; my $y = "$var2$x"; $x=$y },
rsubstr4arg => sub { my $x = rand() ; substr( $x, 0, 0, $var2) ; $x},
rsubstr3arg => sub { my $x = rand() ; substr( $x, 0, 0) = $var2 ; $x},
rconcat => sub { my $x = rand() ; $x = $var2 . $x },
rconcatrev => sub { my $x = rand() ; $x = $x . $var2 },
rconcatrev1 => sub { my $x = rand() ; $x .= $var2 },
rconcat2var => sub { my $x = rand() ; my $y = $var2 . $x; $x=$y },
rpack => sub { my $x = rand() ; $x = pack('a*a*',$var2,$x) },
rpackfixed => sub { my $x = rand() ; $x = pack('a17a*',$var2,$x) },
rjoin => sub { my $x = rand() ; $x = join ('/',$var2, $x ) },
rjoinnosep => sub { my $x = rand() ; $x = join ('', $var2, $x ) },
rsprintf => sub { my $x = rand() ; $x = sprintf('%s%s',$var2,$x) },
}
) ;
timethese ( $count, {
fassign => sub { my $x = $var1 ; $x = "$var2$x" },
}
) ;
sub wtf{ my $x = $var2 ; $x = "$x$var1" }
wtf();
timethese ( $count, {
fassign => sub { my $x = $var1 ; $x = "$var2$x" },
}
) ;
--Duane
* There are too many ways to do it.
On Jun 1, 2011, at 2:02 PM, Ronald J Kimball wrote:
> On Wed, Jun 01, 2011 at 02:36:40PM +0100, Paul Makepeace wrote:
>> On Tue, May 31, 2011 at 22:41, Nick Patch <[email protected]> wrote:
>>> use Benchmark qw( cmpthese );
>>>
>>> cmpthese(-2, {
>>> assign => sub { my $x = 'bar'; $x = "foo/$x" },
>>> substr => sub { my $x = 'bar'; substr $x, 0, 0, 'foo/' },
>>> lvalue => sub { my $x = 'bar'; substr($x, 0, 0) = 'foo/' },
>>> });
>>
>> Oddly(?) join() is 20% faster than assignment:
>>
>> ...
>> join => sub { my $x = 'bar'; $x = join('/', 'foo', 'bar') },
>> oooscf => sub { my $x = 'bar'; $x = File::Spec->catfile($x, 'bar') },
>> fnoscf => sub { my $x = 'bar'; $x = catfile($x, 'bar') },
>
> You're not benchmarking the right behavior. In particular, your join sub
> is not using $x in the call to join.
>
> join => sub { my $x = 'bar'; $x = join('/', 'foo', $x) },
> oooscf => sub { my $x = 'bar'; $x = File::Spec->catfile('foo', $x) },
> fnoscf => sub { my $x = 'bar'; $x = catfile('foo', $x) },
>
> Ronald
>
> _______________________________________________
> Boston-pm mailing list
> [email protected]
> http://mail.pm.org/mailman/listinfo/boston-pm
--
Duane Bronson
[email protected]
http://www.nerdlogic.com/
453 Washington St. #4A
Boston, MA 02111
617.515.2909
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm