I'm not quite sure why the argument passing is faster than setting $_ and accessing it directly. Perhaps it has to do with the assignment operator. My benchmark seems to indicate that this is the case. I also though it might be the global variable itself, so I tried using a lexical. Again, my benchmark indicates that this might be true. I might be testing the wrong things, though.
#!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese timethese); cmpthese timethese(-2, { a => sub { arg('foobar'); }, a_s => sub { arg_shift('foobar'); }, a_a1 => sub { arg_assign1('foobar'); }, a_a2 => sub { arg_assign2('foobar'); }, na => sub { $_ = 'foobar'; noarg(); }, na2 => sub { $_ = 'foobar'; noarg2(); }, }); sub arg { length $_[0] } sub arg_shift { length shift } sub arg_assign1 { $_ = shift; length } sub arg_assign2 { my $x = shift; length $x } sub noarg { length $_ } sub noarg2 { length }
Rate a_a1 na2 na a_a2 a_s a a_a1 538441/s -- -9% -16% -29% -48% -52% na2 590160/s 10% -- -8% -22% -43% -47% na 642280/s 19% 9% -- -15% -38% -42% a_a2 756598/s 41% 28% 18% -- -26% -32% a_s 1027820/s 91% 74% 60% 36% -- -8% a 1112124/s 107% 88% 73% 47% 8% --
Though I must say, while it surprises me that the argument passing is faster, and I agree that I don't like using the global variable willy-nilly, I think you might be engaged in premature optimization. Even the slowest one runs at 181,000 operations per second on your computer.
I have a feeling there are other things in your program that are much slower than this. You may only be curious in the academic sense, but to actually use this as a real optimization strikes me as overkill.
Update: another thing you might consider, which would make this entire discussion moot, is using an iterator instead of callbacks. I'm not saying whether you necessarily should or should not, but just giving another option.
In reply to Re: $_ vs. argument passing
by revdiablo
in thread $_ vs. argument passing
by Dylan
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |