Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I just started learning perl, I came to know that, constant are treated as subroutines in perl. I wonder then why the use of constants can be a good practice if everytime, it is making subroutine call and CPU needs to use stack/jump instruction?
That is a reasonable concern but there is in fact no function call overhead.
Let's first have a look at constant pragma docs
When a constant is used in an expression, Perl replaces it with its value at compile time, and may then optimize the expression further. In particular, any code in an if (CONSTANT) block will be optimized away if the constant is false.
So you are not paying for a function call at runtime.
Further, under Technical Notes it says
In the current implementation, scalar constants are actually inlinable subroutines. As of version 5.004 of Perl, the appropriate scalar constant is inserted directly in place of some subroutine calls, thereby saving the overhead of a subroutine call. See
Constant Functions in perlsub for details about how and when this happens.
We should take note of the "current implementation" phrase, but I think it's safe to expect this not to change in a way that would impose a runtime penalty.
Please read the rest of this section, and make sure to see the Caveats.
The mentioned Constant Functions in perlsub describes
Functions with a prototype of () are potential candidates for inlining. If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without &. Calls made using & are never inlined. (See constant.pm for an easy way to declare most constants.)
This confirms that one is generally fine efficiency wise.
On the other hand, note that the use of constant pragma can raise questions of whether the use of barewords is of concern in your code (which it may or may not be).
The "good practice" regards the programming benefits of using constant (read-only) declarations for variables that should not be changing. Such practice generally improves the code substantially.
This question already has answers here:
When should I use the & to call a Perl subroutine?
(4 answers)
Closed 9 years ago.
Every now and then I see Perl scripts where subroutines are called with a leading '&'.
Is this legacy, or does it give any benefit?
As calling the subroutine without the ampersand sign works as well.
sub mysub {
print "mysub\n";
}
mysub;
&mysub;
Thx/Hermann
Calling with & is generally a code smell that somebody doesn't know what they're doing and are in a Perl4 mindset. In your specific example, it works exactly the same. However, calling with & disables function prototypes, so advanced users may use it in certain circumstances. You should expect to see a comment why next to the call in that case.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When should I use the & to call a Perl subroutine?
In perl scripts, why is that method of invoking the function is written differently some times. I see &function and sometimes function(). Are they both the same and this is just a style that one would want to flaunt? If they are the same, why are they both available, would not one just suffice? I am guessing there is some semantic difference between the both the methods which distinguishes them from each other ... but at what kind of circumstances?
--- Since I cannot answer my own question for timeout reasons -- I am updating the answer in the section of question itself. When I get a chance to update the answer block, I will put it there.
I found the relevant text in 'Learning Perl' book..thanks for the tip though. Chapter 4: Subroutines -- Omitting the Ampersand.
I was more interested in ampersand & usage for perl functions. If a subroutine is already defined before being invoked, then subroutine can be invoked without using & while calling the function similar to invoking the builtin functions. & is also used to distinguish between the builtin functions and the user defined functions if the function to be invoked uses the same name that of one of the builtin function, provided it is defined before being invoked.
Usage of (), is merely to justify the passing of the arguments to the subroutines, while if not used, the default list of current arguments are passed in the form #_. If the arguments are specified in () for a subroutine, it is assumed to be a subroutine and is invoked even if not previously defined while parsing.
It has very specific uses:
& tells Perl to ignore the sub's prototype.
& can allow you to use the caller's #_. (&foo; with no parens or arguments).
goto &foo; and defined &foo.
Getting a reference (e.g. \&foo).
Some people (mostly beginners) use it to distinguish user subs from builtin functions, since builtin functions cannot be preceded by &.
As mentioned by #manatwork and #KeithThompson you can find information in these articles:
A general description - What's the difference between calling a function as &foo and foo()?
Subtle information about using & or not for a function call - perlsub: Perl Subroutines: Description.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
I was wondering if you had any basic tips to improve the performance of a Perl script performance (like memoizing determinist functions)?
Install Devel::NYTProf
run your script with it: perl -d:NYTProf some_perl.pl
convert the output file into a nice report: nytprofhtml -f nytprof
open the report in a web browser: firefox nytprof/index.html
look for whatever is taking the most time
determine if that is the right algorithm for the job (e.g. are you using an O(n2) algorithm where a O(n) algorithm would also work?)
extract the slow code to a separate script that can be run by itself
write a second (or more) version of the slow code
use Benchmark to compare them (remember to use data that you expect to see in the wild, some algorithms do great for small numbers of items, but are terrible when the number of items increase)
when you have proven that you have faster code, modify the original and go back to step 2 until your code is fast enough or you can't improve it any more
if it is still too slow, ask how to do X faster here (be as detailed about X as you can be)
You should profile first. Rules are made to be broken.
Some very basic tips:
Avoid slurping. There are occasions where slurping more than a line is justified, but slurping whole files everywhere is going to exact a price.
Avoid passing large lists to subroutines.
If you have multi-level hashes or arrays, avoid repeatedly dereferencing multiple levels. Store a reference to the deepest applicable level in a lexical variable and use that.
Declare your variables in the smallest scope possible. I am not sure if this is an optimization in and of itself, but frequently will allow you to see more clearly, and that is key to improving performance.
The basic tips for improving the performance of Perl scripts consists of general approaches that apply everywhere, and some very Perl-specific things.
Things like:
measure, don't guess, and target expensive areas only. Your ROI will be much higher.
cache unchanging expensive results if you're going to use them a bit.
don't do something manually when there's a function that will do it for you. This is the difference between interpreted and compiled speed.
use CPAN, there's a module for everything, usually written by people who know Perl better than us mere mortals.
This is not something that's easy to distil into a short pithy answer.
I will give one piece of advice. The best way to improve the performance of your code is to post specific bits of it here on SO and wait for the likes of brian d foy to find it :-)
I recently found out that profiling is very useful, and that Devel::NYTProf is very good at it.. Profiling stops you from unnecessary optimizing and helps you fix the biggest bottlenecks first.
Of course, having some knowledge of what not to do helps, but guess that's not very perl specific..
A list of common perl performance gotchas would be nice though :)
Update:
here is one: glob() sorts if you don't tell it otherwise :|
don't copy large amounts of data around, use references (e.g.: Use scalar references to pass large data without copying. )
Duplicate of: How can I speed up my Perl program?
Many good suggestions here already, here are a few more:
Avoid repeatedly packing and unpacking arrays, especially when they are large
pack and unpack are very fast, but split is sometimes faster
Inline small portions of code rather than breaking everything into subroutines (you can easily go too far with this, so profile to find the hot spots).
If you want an array of aliases, know your data is mutable, or promise not to change the values, using sub{\#_}->(retuns_a_list()) is around 40% faster than [returns_a_list()] (you don't have to inline the subroutine, I usually call it sub cap {\#_} (short for capture)
And if you really, really need to improve the speed of method calls on certain objects, you can use closure based objects. Here is an excerpt from my module List::Gen discussing the curse method of creating closure objects:
curse HASHREF PACKAGE
many of the functions in this package utilize closure objects to avoid the speed penalty of dereferencing fields in their object during each access. curse is similar to bless for these objects and while a blessing makes a reference into a member of an existing package, a curse conjures a new package to do the reference's bidding
package Closure::Object;
sub new {
my ($class, $name, $value) = #_;
curse {
get => sub {$value},
set => sub {$value = $_[1]},
name => sub {$name},
} => $class
}
Closure::Object is functionally equivalent to the following normal perl object, but with faster method calls since there are no hash lookups or other dereferences (around 40-50% faster for short getter/setter type methods)
package Normal::Object;
sub new {
my ($class, $name, $value) = #_;
bless {
name => $name,
value => $value,
} => $class
}
sub get {$_[0]{value}}
sub set {$_[0]{value} = $_[1]}
sub name {$_[0]{name}}
the trade off is in creation time / memory, since any good curse requires drawing at least a few pentagrams in the blood of an innocent package. the returned object is blessed into the conjured package, which inherits from the provided PACKAGE.
when fast just isn't fast enough, since most cursed methods don't need to be passed their object, the fastest way to call the method is:
my $obj = Closure::Object->new('tim', 3);
my $set = $obj->{set}; # fetch the closure
# or $obj->can('set')
$set->(undef, $_) for 1 .. 1_000_000; # call without first arg
which is around 70% faster than pre-caching a method from a normal object for short getter/setter methods.
This question reminds me of the advice of Tim Bunce, maintainer of Devel::NYTProf.
To summarize, don't do it unless you really have to.
My favorite quote from his presentation:
“The First Rule of Program
Optimization: Don't do it.
The Second Rule of Program Optimization (for experts only!): Don't do it yet.”
-Michael A. Jackson
[emphasis added]
Here are a few specific things that haven't been mentioned yet:
use tr/// instead of s/// wherever possible
use index() to match exact substrings instead of a regex
never ever use $^, $& and $-. These are the dreaded regex match variables that slow all regexes. There are alternatives that do not impose a penalty.
Revenge of the match vars, when using the English module, exclude match variable aliasing. That is, do use English '-no_match_vars'; instead of just use English;
More info can be found in perlop, perlfunc and perlvar.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How do I implement dispatch tables in Perl?
I have a hash table that contains commands such as int(rand()) etc.
How do I execute those commands?
You can use eval($str) to execute Perl code you store in a string variable, $str. You could alternatively store your code as function references within a hash, so something like:
$hash{'random'} = sub { int(rand()) };
This way, you could write $hash{'random'}->() to execute the function whenever you want a random value.
See also Implementing Dispatch Tables on PerlMonks.
As other have said, you can execute them using eval. However, please note that executing arbitrary strings of possibly tainted origin via eval is a major security hole, as well as prone to be slow if performance of your application matters.
You can use the Safe module to remove the security hole (not sure how bulletproof that is but much better than naked eval), but performance issues will always be there as Perl will have to compile your code prior to executing it WHILE executing the main program.