in reply to $_ vs. argument passing
On the other hand, your $_ = 'foobar' induces a string copy of 'foobar' every single time that statement is executed. Since calculating the length is easy, the additional overhead of the extra copying *really* stands out.
I added these two subs to the benchmark:
And reran it (dropping the time from 60s each to 10s each, because I'm far too impatient to wait six minutes for the test to rerun):sub xarg { my $tmp = $_[0]; length $tmp } sub xarg_shift { my $tmp = shift; length $tmp }
Note that they're still not on equal footing: the additional symbol table lookup needed to find the location of $_ *really* hurts. This is because the work needed to find $_ in the symbol table is far greater than the work needed to find the length of it (because the length is precomputed).Benchmark: running arg, arg_shift, noarg, noarg2, xarg, xarg_shift for + at least 10 CPU seconds... arg: 10 wallclock secs (10.52 usr + -0.01 sys = 10.51 CPU) @ 48 +9653.09/s (n=5146254) arg_shift: 10 wallclock secs (10.28 usr + 0.00 sys = 10.28 CPU) @ 41 +4663.33/s (n=4262739) noarg: 9 wallclock secs (10.00 usr + 0.00 sys = 10.00 CPU) @ 28 +7455.40/s (n=2874554) noarg2: 11 wallclock secs (10.55 usr + 0.00 sys = 10.55 CPU) @ 28 +2535.73/s (n=2980752) xarg: 10 wallclock secs (10.59 usr + 0.00 sys = 10.59 CPU) @ 33 +7761.28/s (n=3576892) xarg_shift: 10 wallclock secs (10.39 usr + 0.01 sys = 10.40 CPU) @ 29 +7917.40/s (n=3098341) Rate noarg2 noarg xarg_shift xarg arg_shift + arg noarg2 282536/s -- -2% -5% -16% -32% + -42% noarg 287455/s 2% -- -4% -15% -31% + -41% xarg_shift 297917/s 5% 4% -- -12% -28% + -39% xarg 337761/s 20% 18% 13% -- -19% + -31% arg_shift 414663/s 47% 44% 39% 23% -- + -15% arg 489653/s 73% 70% 64% 45% 18% + --
$"=$,,$_=q>|\p4<6 8p<M/_|<('=> .q>.<4-KI<l|2$<6%s!<qn#F<>;$, .=pack'N*',"@{[unpack'C*',$_] }"for split/</;$_=$,,y[A-Z a-z] {}cd;print lc
|
|---|