in reply to $_ vs. argument passing

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.

Replies are listed 'Best First'.
Re^2: $_ vs. argument passing
by Dylan (Monk) on Dec 22, 2004 at 19:53 UTC
    I do not care which is faster. I will use argument passing anyway, I only care what is the best design. I merely wanted to know how much slower argument passing would be... And since it is not, that's icing on the cake.
      I do not care which is faster.

      Could've fooled me, based on your question. At least half of it is dedicated to talking about the speed... but I digress. :-)

      I only care what is the best design.

      If you want to know how other people feel about it, then I think the best option would be a design similar to the one chromatic described. But if you are set on using callbacks, then you can mark me down in the "argument passing" column.

        Well, I'd like to know what the speed is, but I don't really care. I mean, my laptop is 1ghz. My workstation box is 2ghz. Plus this is (as someone else mentioned) I/O intensive. I want it to be clean, and I'm merely curious about speed.

        Now, as to callbacks. I'm using them because of the problem domain I'm trying to fill. The problem domain is to make something to allow me to replace ttree (an ugly script that comes with Template Toolkit). Which means I need to do different things depending on the filename.

        This design fits my problem very well, and *maybe* it'll fit other people's problems, too. There is always File::Find::Iterator on CPAN already for those that want iterators. The real usefulness of this module is to be able to say "process all .pl files with this function, and process all .pm files with this function, etc".