in reply to Is there any (performance) benefit to importing functions?
I've noticed that there are some functions that don't require use-ing or require-ing to use: for instance, the Time::HiRes:: functions, the utf8:: utility functions, Cwd::getcwd(), etc.
This isn't quite correct - the only one of those that is loaded automatically by Perl is utf8:
$ perl -wMstrict -le 'print Time::HiRes::gettimeofday()' Undefined subroutine &Time::HiRes::gettimeofday called at -e line 1. $ perl -wMstrict -le 'print Cwd::getcwd()' Undefined subroutine &Cwd::getcwd called at -e line 1. $ perl -wMstrict -le 'print utf8::valid("foo")' 1
However, if you have noticed this behavior in a longer script, then note that if any other piece of code you've loaded does e.g. use Cwd; or require Cwd;, then you will be able to do Cwd::getcwd() in your code regardless of whether or not you have loaded Cwd yourself. This is because of the way Perl's Symbol Tables work: once Perl sees package Cwd; sub getcwd { ... } or equivalent, then the symbol table entry &Cwd::getcwd will exist.
where do I find a reference/list of these functions which require no require or use to use?
It's pretty rare that Perl loads modules automatically, and I don't think there is a reference other than a few mentions sprinkled throughout the docs. Really the only one I can think of off the top of my head at the moment is utf8, as I showed above. Then there are those that are loaded on demand only, such as File::Glob - note how I have to use the glob operator <*> before I can access File::Glob::*:
$ perl -wMstrict -le ' print join ",", File::Glob::bsd_glob("{x,y} +={a,b}")' Undefined subroutine &File::Glob::bsd_glob called at -e line 1. $ perl -wMstrict -le '<*>; print join ",", File::Glob::bsd_glob("{x,y} +={a,b}")' x=a,x=b,y=a,y=b
Then there are those that are documented to be loaded automatically, such as IO::Handle and charnames (at least in recent versions of Perl), but some quick testing seems to show that these don't behave like File::Glob in that I still have to use them explicitly if I want to access the functions in the modules.
Also, note there isn't really a standard behavior for modules in Perl. In this node I wrote at length about how importing from modules works, and note some of the general statements such as "Because Perl is very flexible in what it allows module authors to do, it isn't easy to give some general rules as to how modules act, beyond some guidelines and best practices about how modules should be written, and based on that some rules of thumb of what to expect. So you'll have to look at the documentation of each of the modules to see what effects useing them will have." I also recommend a thorough read of perlmod.
What does this mean? I would recommend that you always explicitly use modules whose functions you want to use in your code. That way, a reader of the code won't be confused where those functions are coming from, and you wouldn't be relying on any action-at-a-distance behavior, as I think you are when you talk about e.g. Cwd::getcwd() being loaded automatically. The only exception to this rule might be utf8, because use utf8; has the special effect of declaring the source code to be encoded in UTF-8. (If I think of or am reminded of any other such exceptions I can update this node.)
But that got me thinking also about (2nd question) whether or not it makes a performance difference when using "long" package names
A Benchmark with the following constructed single test case on my machine seems to show that there is no significant difference between the two across various versions of Perl.
use warnings; use strict; use Benchmark qw/cmpthese/; { package Foo; sub bar { return $_[0] + $_[1] } } BEGIN { *bar = \&Foo::bar } # import cmpthese(-2, { imported => sub { bar(2,3)==5 or die; }, package => sub { Foo::bar(2,3)==5 or die; }, });
I mean does perl have to convert long names into paths or something to locate the function everytime
No, although I'm not an expert on the internals, I'm pretty sure Perl does not have to do that. In my example code above, note that the function call bar() is basically just short for main::bar() (since the default package is main), and both main::bar() and Foo::bar() refer to the same piece of code.
What does this mean? In my opinion the performance difference is small enough that it should be ignored. What shouldn't be ignored is that imported functions save typing. (Another smaller factor to consider might be testing: If you use the full package name, mocking those functions is a little more annoying because you have to override them in the originating package instead of just the package under test.)
Update: Typo fix and minor re-wording for clarity.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Is there any (performance) benefit to importing functions?
by YenForYang (Beadle) on Feb 10, 2018 at 23:31 UTC |