www.perl.com
O'Reilly Network.oreilly.comSafari Bookshelf.Conferences. Sign In/My Account | View Cart   
Articles Weblogs Books Learning Lab News  
advertisement
Where 2.0 Conference June 13-14, 2006, San Jose, CA


Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Related O'Reilly Books



   Print.Print

A Timely Start

by Jean-Louis Leroy
December 21, 2005

This article is a follow-up to the lightning talk I delivered at the recent YAPC::Europe 2005 that took place in Braga, Portugal: "Perl Vs. Korn Shell: 1-1." I presented two case studies taken from my experience as Perl expert at the Agency (they have asked me to remain discreet about their real name, but rest reassured, it's not the CIA, it's a European agency).

In the first case, I explained how I had rewritten a heavily used Korn shell script in Perl, in the process bringing its execution time from a half-hour down to ten seconds. The audience laughed and applauded loudly at that point of my talk.

Then I proceeded to the second case, where the situation was not so rosy for Perl. One of my colleagues had rewritten a simple ksh script that did a few computations then transferred a file over FTP. The rewrite in Perl ran ten times slower.

Slower?

My job was to investigate. I found a couple of obvious ways of speeding up the Perl script. First I removed hidden calls to subprocesses:

use Shell qw( date which );
# ...
$now   = date();
$where = which 'some_command';

Then I replaced a few use directives with calls to require. If you're going to use the features contained in a module only conditionally, require may be preferable, because perl always executes use directives at compile time.

Take this code:

use Pod::Usage;

# $help set from command-line option
if ($help) {
    pod2usage(-exitstatus => 0);
}

This loads Pod::Usage, even if $help is false. The following change won't help, though:

# $help set from command-line option
if ($help) {
    use Pod::Usage;
    pod2usage(-exitstatus => 0);
}

This just gives the illusion that the program loads Pod::Usage only when necessary. The right answer is:

# $help set from command-line option
if ($help) {
    require Pod::Usage;
    Pod::Usage::pod2usage(-exitstatus => 0);
}

After these changes the situation had improved: the Perl version was only five times slower now. I pulled out the profiler. Sadly, most of the time still went to loading modules, especially Net::FTP. Of course, we always needed that.

If you dig in, you realize that Net::FTP is not the only culprit. It loads other modules that in turn load other modules, and so on. Here is the complete list:

/.../libnet.cfg
Carp.pm
Config.pm
Errno.pm
Exporter.pm
Exporter/Heavy.pm
IO.pm
IO/Handle.pm
IO/Socket.pm
IO/Socket/INET.pm
IO/Socket/UNIX.pm
Net/Cmd.pm
Net/Config.pm
Net/FTP.pm
SelectSaver.pm
Socket.pm
Symbol.pm
Time/Local.pm
XSLoader.pm
strict.pm
vars.pm
warnings.pm
warnings/register.pm

This is not by itself a bad thing: modules are there to promote code reuse, after all, so in theory, the more modules a module uses, the better. It usually shows that it's not reinventing wheels. Modules are good and account for much of Perl's success. You can solve so many problems in ten lines: use this, use that, use this too, grab this from CPAN, write three lines yourself--bang! problem solved.

Perl Best Practices

Related Reading

Perl Best Practices
By Damian Conway

Table of Contents
Index
Sample Chapter

Read Online--Safari
Search this book on Safari:
 

Code Fragments only

Pages: 1, 2, 3

Next Pagearrow



Sponsored By:




Contact Us | Advertise with Us | Privacy Policy | Press Center | Jobs | Submissions Guidelines

Copyright © 2000-2006 O’Reilly Media, Inc. All Rights Reserved.
All trademarks and registered trademarks appearing on the O'Reilly Network are the property of their respective owners.

For problems or assistance with this site, email