I always wondered why some people write unreadable Perl. The most common reason given seems to be ‘Its faster that way'.
And so… using DTrace, and the extra probes (see the subversion repository with a patched Perl 5.8.8) I added, I thought I'd take a look.
$1
Using these probes, we can write some ‘D' that tells us what Perl is doing at each of its phases – startup, parsing, execution, and cleanup.
First off, accessing function call parameters:
Given 3 essentially identical programs
$1
$1
$1
There is a myth that using $_[0] is faster, as it doesn't create a temporary variable…
Dtrace (using the general perl stats gathering dtrace script) shows this to be untrue:
$1
Counting up the number of allocations and deallocations in the (0/1) output – and
“<– func, ./call2.pl (1/0) ” is always the same… one allocation. After all the test runs, I also print out the total allocations for the script,
and it seems that the “my $val = shift” version is the most efficient –
using two fewer allocations (apparently during the parse phase). The deallocation count is interesting too – with “$[0]” using 5 more deallocations during
the parse phase and “my ($val) = @;” using one more than the “my $val = shift” option. In an attempt to reduce the allocations doesn't seem to help – the following code resulting in 474 allocations,
shift case, but with 3 extra deallocations, again in the parsing phase. Increasing the number of times that func
is called only increases the benefits of using shift.
$1
Interestingly, “my $val = shift” is not only the fastest of the conventions tested, but it also seems that none of the conventions tested cause allocations at run time – they are all done during the parse phase. I guess I'll have to construct a more complex case, using references / hashes – next time 🙂