Subject: | AutoLoader:can: Slowness because of numerous stat(2) calls |
An OO program, which uses AutoLoader 5.63 and can(), may have
performance problems because of many stat(2) calls. Consider the
following program
package Bla;
use AutoLoader qw(AUTOLOAD);
my $x = bless {}, __PACKAGE__;
for (1..100) {
$x->can("not_existent");
}
__END__
With 5.8.8 and AutoLoader 5.60, it seems that there is no attempt to
autoload the "not_existent" method:
$ truss perl5.8.8 Bla.pm | & grep 'stat.*not_existent.al' | wc -l
0
With 5.10.0 or 5.8.8 with AutoLoader 5.63, every can() call would cause
a stat() call, which may be expensive:
$ truss perl5.8.8
-Mblib=/usr/local/src/CPAN/build/AutoLoader-5.63-zw4plq Bla.pm | & grep
'stat.*not_existent.al' | wc -l
900
$ truss perl5.10.0 Bla.pm | & grep 'stat.*not_existent.al' | wc -l
500
The root of the problem is that the "require" in AutoLoader::can is
called every time. A possible fix is to fake %INC so that require is
called only once. See the attached patch.
I see two minor problems with the patch, though probably not really
relevant:
* Programs which use the keys or values of %INC (e.g. for reloading)
will be misleaded
* Formerly a (long-running) program would benefit from a late
installation of the missing autoloaded file.
See also ticket where this problem was reported originally:
http://rt.cpan.org/Ticket/Display.html?id=30929
Regards,
Slaven
Subject: | AutoLoader-can.patch |
#### Patch data follows ####
diff -up '../build/AutoLoader-5.63-zw4plq/lib/AutoLoader.pm' 'AutoLoader-5.63/lib/AutoLoader.pm'
Index: ./lib/AutoLoader.pm
--- ./lib/AutoLoader.pm Wed Jan 17 14:18:54 2007
+++ ./lib/AutoLoader.pm Tue Nov 27 23:29:04 2007
@@ -60,7 +60,7 @@ sub can {
my $package = ref( $self ) || $self;
my $filename = AutoLoader::find_filename( $package . '::' . $method );
local $@;
- return unless eval { require $filename };
+ $INC{$filename} = undef, return unless eval { require $filename };
no strict 'refs';
return \&{ $package . '::' . $method };
#### End of Patch data ####