require vs Module::Load benchmark

Since I often do:

sub some_func {
    require Some::CPAN::Module;
    ....
}

to delay loading of modules, I am interested in how much overhead this introduces.

After first successful require(), the subsequent require()'s of the same module is very fast (around 0.08µ on my PC) because all Perl does is just convert Some::CPAN::Module to Some/CPAN/Module.pm and check this against %INC. This kind of overhead is comparable to that of an empty subroutine call.

If we change the require line to

load "Some::CPAN::Module";

we then get an overhead of about 12µs (a factor of 150). This is because at this scale, each operation matters. For convenience, load() does some extra stuffs: at least a few extra subroutine calls and a regex match. These add up quite a bit. (Btw, there's a unused call to _who() in load() which can be commented out to save around 1µs, so it's 11µs, but still...)

Of course, in most cases this overhead does not matter.

A failed require(), on the other hand, is relatively more expensive. Both these code:

# check optional module to enable feature
eval { require Foo::Bar };

and

# check optional module to enable feature
eval { load "Foo::Bar" };

takes around 20µs and 55µs respectively. On my slow netbook it's around 170µs (0.17ms) and 500µs (0.5ms), respectively. This is because require() searches the filesystem each time. The longer your @INC is, the longer it takes each for require(). The load() version is more than twice slower because it tries "Foo/Bar.pm" as well as "Foo/Bar" plus using File::Spec::Unix for path manipulation which is slower than its direct variant.

Again, in most cases this overhead does not matter.

Leave a comment

About Steven Haryanto

user-pic A programmer (mostly Perl 5 nowadays). My CPAN ID: SHARYANTO. I'm sedusedan on perlmonks. My twitter is stevenharyanto (but I don't tweet much). Follow me on github: sharyanto.