Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
I have a function that is called in an inner loop that takes several arguments; is it faster to access those arguments by something like
my ($arg1, $arg2, $arg3) = @_;
or the normal way like
my $arg1 = shift; my $arg2 = shift; my $arg3 = shift;
thanks for the help!
-Dan
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Silly question about function args
by tachyon (Chancellor) on Feb 09, 2003 at 10:36 UTC | |
Passing args to a function is unlikely to be a significant bottleneck as noted extensively. To optimise code speed you need to attack the bottlenecks. To do this you need to know where they are. This are quite often not where you think they are (in my experience!). Devel::Dprof is the usual tool of choice for code speed profiling. Here is an example Devel::Dprof is your friend with extensive discussion. If you are reading large files you can get several orders of magnitude speed increase by reading in blocks of data rather than single lines. See Re: Performance Question cheers tachyon s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print | [reply] |
|
Re: Silly question about function args
by rob_au (Abbot) on Feb 09, 2003 at 09:47 UTC | |
perl -le 'print+unpack("N",pack("B32","00000000000000000000001000101110"))' | [reply] |
by demerphq (Chancellor) on Feb 09, 2003 at 09:53 UTC | |
--- demerphq | [reply] |
|
Re: Silly question about function args
by BrowserUk (Patriarch) on Feb 09, 2003 at 09:44 UTC | |
You pays your money and takes your choice:^)
Direct access is hands down fastest, with shift second and list assignment last. Directly accessing 100 args is nearly as fast as shifting 3!; However, what if any discernable difference it makes will depend very much on how many times your calling the sub, how deeply the call stack grows and how much you are doing in the sub. Calling small subs with many parameters many times benefiting much more than a few calls to subs that do lots of work. Examine what is said, not who speaks. The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead. | [reply] [d/l] |
|
Re: Silly question about function args
by Paladin (Vicar) on Feb 09, 2003 at 09:09 UTC | |
| [reply] [d/l] [select] |
by integral (Hermit) on Feb 09, 2003 at 09:46 UTC | |
Update: BrowserUk's answer demonstrates this better.
| [reply] [d/l] |
by demerphq (Chancellor) on Feb 09, 2003 at 10:10 UTC | |
Exactly. Inline the function entirely. Thats much faster. and to access them inplace in @_ Persoanlly I would caution against this. An innocuous change of Would alter the original variable. Better to do away with the subroutine entirely. Then at least this effect is obvious and as I said you avoid the subroutine jump overhead.
--- demerphq | [reply] [d/l] |
|
Re: Silly question about function args
by blokhead (Monsignor) on Feb 09, 2003 at 09:19 UTC | |
Anyway, I will attempt to answer your question. You should look at the Benchmark module comes with your Perl distribution. I ran a few test cases, and found the shift method faster for very small arguments (ints, small strings, references), and the @_ method faster for passing larger objects (strings). Try it out yourself with whatever data is most common in your app. blokhead | [reply] |
|
Re: Silly question about function args
by demerphq (Chancellor) on Feb 09, 2003 at 09:47 UTC | |
But when I add some even rudimentary code to the subs, like the difference gets swamped to the point of being noise. Go ahead and make the change, but Id be quite suprised if benchmark showed much difference. You may need to make the function inline to see any real gains. Other tricks like using static variables (reduces allocation overhead but renders the code not thread safe). You may need to consider a lot of things. Poorly constructed regexes can chew up a lot of time. Without seeing the code and its usage theres no way anyone here could make any specific recommendations. :-) You should have a look at When perl is not quite fast enough HTH
--- demerphq | [reply] [d/l] [select] |
|
Re: Silly question about function args
by Coruscate (Sexton) on Feb 09, 2003 at 10:13 UTC | |
When it comes to receiving your arguments, I wouldn't focus on speed as much as I would on appearance. If you are passing one or two arguments, feel free to shift them off. Myself, I generally shift for only one or two args, any more I use the @_ method, not for speed, but for shorter, cleaner, uncluttered code. Just to exagerate my point, which snippet looks nicer?
Update: Another reason I really like named arguments is code that looks like the following:
If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, reply to this node or /msg me to tell me what is wrong with the post, so that I may update the node to the best of my ability. If you do not inform me as to why the post deserved a downvote, your vote does not have any significance and will be disregarded. | [reply] [d/l] [select] |
|
Re: Silly question about function args
by crenz (Priest) on Feb 09, 2003 at 18:14 UTC | |
You might want to take a look at Inline::C on CPAN. It allows you to embed C source directly in your perl script. I suppose that calling a C function this way takes longer than calling a perl subroutine, so you should probably implement a whole loop in C and call that function only a few times. | [reply] |
|
Re: Silly question about function args
by pg (Canon) on Feb 09, 2003 at 18:16 UTC | |
If performance is so important to your application, and you even start to look at this kind of subtle place, then why not go c, instead of perl. You said it would run overnight, is it active all the night? or idle most of the time? if it is active the whole night, go c. Choose the right tool for the right thing. | [reply] |
|
Re: Silly question about function args
by tadman (Prior) on Feb 09, 2003 at 13:19 UTC | |
I think it's appropriate to save shift for those special cases where the modified @_ is going to be used, something which is certainly not most of the time. | [reply] |