While generally not considered best practice, I think few people would complain about accessing them directly as $_[0] and $_[1] if the function itself is only a few lines.

Interesting – there seems to be a split on this. I don’t like to see direct access of @_ elements in any code. Although admittedly I occasionally do it in one-liners I always feel dirty afterwards. I think Juster agrees and zloyrusskiy disagrees.

I also like the array unpacking idiom (my %args = @_). I flit between using it and not using it. Normally, speed of unpacking doesn’t matter *that* much to me apart from the type of shims I discussed in the Abstraction and Subroutines post.

You’ve piqued my interest in Perl 6 with your mention of the flexible handling of subroutine arguments. Although I’m also a little bit sad that Perl 5 doesn’t have anything as good as lisp macros. Even as weak a variant as emacs lisp has such goodies as keyword parameters easily bolted on by macros in a library.

Yes I understand what you’re trying to show but its nice to see that the idiomatic empty loop is actually faster in Perl :)

/I3az/

]]>By: Kevan Bensonhttps://curiousprogrammer.wordpress.com/2010/06/21/benchmarking-perl-subroutine-calls/#comment-8114
Tue, 22 Jun 2010 22:38:33 +0000http://curiousprogrammer.wordpress.com/?p=1067#comment-8114@Jared – Understood. My point wasn’t to show Perl was faster in a specific portion of your tests, but to show that quick benchmarks often yield less than pristine results.

For example, you make the assumption that you need to assign variables for the passed values in f2. While generally not considered best practice, I think few people would complain about accessing them directly as $_[0] and $_[1] if the function itself is only a few lines (I know I can make arguments both ways for a function that small). That brings the results much closer to what you are seeing in Python, but still slower.

The directions the languages have gone are very different, and it might be more fruitful to benchmark common usages in each (although that’s a much larger task). Perl’s arguments as a list with light prototyping sugar yields some interesting and useful practices, but so do python’s stricter prototypes and polymorphism. If each is commonly used in a manner that requires extra processing, that skews the result. Your testing of a function that unpacks some variables shows you at least thought about the base case of this. For example, I’m a fan of using hash semantics to define the list of variables passed in as a list of named parameters, but that’s less than ideal for speed. E.g.
sub myfunc {
my %ops = @_;
}
myfunc(param1 => ‘value1′, param2 => ‘value2′);

An interesting tangent to this is how much boilerplate the language lets you remove from this. Chromatic touched on this when referring to a YAPC talk in his blog at http://www.modernperlbooks.com/mt/2010/06/when-assembly-leaks-through.html. Perl 6 gives you everything I’ve mentioned from both languages plus much more; real named arguments, positional arguments, or slurpy arguments, and you can mix them in a single prototype. Add multiple dispatch and… wow. Yes, this is blatant fanboi advertising. I can’t help it. ;)

@draegtun & Kevan – Okay, it is kinda nice to know how to improve the loop slightly. I remember the days that 1 .. 10_000_000 would construct an array in memory :)

But that isn’t what I’m interested in here. I’m interested in how fast subroutine calls are. That is the reason I measured the loop speed first so I can take it out of the equation. And in my tests, it looks like Python calls are significantly faster than Perl calls (although not sufficiently faster for me to care/switch).

Note the last one. The iterator variable is still available through the topic, $_. There's no reason to assign it to a separate variable every iteration, and if you need it, that's what the topic is for.

Just because Perl allows you to write in any style you want, doesn't mean the code will be optimal for execution.

]]>By: Adam Kennedyhttps://curiousprogrammer.wordpress.com/2010/06/21/benchmarking-perl-subroutine-calls/#comment-8109
Tue, 22 Jun 2010 11:32:04 +0000http://curiousprogrammer.wordpress.com/?p=1067#comment-8109For f1, in Perl if a function takes no parameters I believe you can speed it up by telling it as much via prototypes.

sub f1 () {

}

]]>By: Jaredhttps://curiousprogrammer.wordpress.com/2010/06/21/benchmarking-perl-subroutine-calls/#comment-8108
Tue, 22 Jun 2010 08:01:35 +0000http://curiousprogrammer.wordpress.com/?p=1067#comment-8108@Nilson – I tried strings which just made it slower. Python was able to handle them better. Maybe it is the reassigning of the parameter list from @_ that is slowing Perl down.

@James – I’m using version 5.10.1 which should have fixed that regression. However, the subroutine using shift is still slightly quicker.

I’ll post more benchmarks shortly.

]]>By: Jameshttps://curiousprogrammer.wordpress.com/2010/06/21/benchmarking-perl-subroutine-calls/#comment-8106
Mon, 21 Jun 2010 17:35:31 +0000http://curiousprogrammer.wordpress.com/?p=1067#comment-8106What version of perl are you running this under?
I believe that list assignment is usually slower than shifting each item off of @_, and there was a regression in 5.10.0 that slowed it down much more. I would be interested in seeing how this version of f2 stacks up: