Re: Perl make depend made faster

Luca Lizzeri (lizzeri@mbox.vol.it)
Sat, 14 Sep 1996 20:42:37 +0200 (MET DST)


On Sun, 15 Sep 1996, Keith Owens wrote:

> On my 486 DX2/66 SCSI-2 with 20 Mb, depend.awk took 3:34 wall clock (best
> time), depend.pl took 2:30 (worst time). A couple of tweaks to depend.pl
> knocked that down even more, to 2:07.
>

Argh. What has escaped me ?

> Doing "undef $/;" and replacing "$program = join '', <FILE>' with "$program =
> <FILE>;" took 20 seconds off the wall clock.

Thanks. That saved 12 seconds on my machine.

> Removing all "my" keywords took out another second or so.
>

1/2 second here. It's in :)

> Unfortunately the technique "foreach $file (@ARGV); ... push(@ARGV,$rfname);"
> does not work. The "foreach" list is evaluated once, new files are pushed
> onto @ARGV but never actually processed (perl 5.001m). This results in
> missing dependencies in /drivers/sbus/char/.depend.
>

Not so in perl5.003. I checked very thoroughly the .depend files. Must be
a perl change. However, I changed it to something else from what you
proposed.

> Speed up patch and correction to ARGV list follow.
>
[snip]
> -foreach $file ( @ARGV ) {
> +for ($i = 0; $i <= $#ARGV; ++$i) {
> + $file = $ARGV[$i];

I tried hard to avoid things like this, keeping in mind people with no
math coprocessor. This works and is even shorter than the original (
a very important point with some perl gurus :)

while ( $file = shift ) {

I include here the latest diff (it's only against depend.pl, so you'll
have to have the preceding one installed, then cd to the scripts directory
and apply it).

With this, I am down to 45.47 from 1:25.58 wall time ( 26.35 from 62.61
user !) on my work machine (P100, 24 MB).

Luca Lizzeri

--- depend.pl.orig Sat Sep 14 18:10:04 1996
+++ depend.pl Sat Sep 14 20:38:23 1996
@@ -1,9 +1,9 @@
#!/usr/bin/perl -w
-# depend.pl 1.0, the Revolution Revision
+# depend.pl 1.1, the Revolution Revision #2
# This is the old depend.awk drawn, quartered and given new life
# by Luca Lizzeri ( lizzeri@mbox.vol.it ).
+# With go-faster suggestions by Keith Owens ( kaos@audio.apana.org.au )
# Use it, misuse it or modify it as you see fit.
-# If it breaks you get to keep both pieces.


# Check sanity of environment
@@ -13,46 +13,48 @@
die "Environment variable HPATH is not set\n" unless $ENV{"HPATH"};


+# Swallow entire files at a single gulp
+
+
+undef $/;
+
+
# Massage HPATH into parray


-my @parray = split( ' ' , $ENV{"HPATH"} );
-grep ( do { s/^I//; s/[\/\s]*$/\//; } && 0 , @parray );
+my @parray = grep ( do { s/^I//; s/[\/\s]*$/\//; } && 1 , split( ' ' , $ENV{"HPATH"} ) );


# Iterate on input files


-foreach $file ( @ARGV ) {
+while ( $file = shift ) {


# Sensible if boring initializations ..


- my $hasdep = 0, $hasconfig = 0, $needsconfig = 0;
- my $cmd = '', $depname = '', $relpath = '';
- my @includes = ();
+ $hasdep = 0, $hasconfig = 0, $needsconfig = 0;
+ $cmd = '', $depname = '', $relpath = '';
+ @includes = ();


# Massage filename into $depname, $relpath, $cmd


- ( $depname = $file ) =~ s/\.[cS]$/.o: /;
( $relpath = $file) =~ s/\/?[^\/]*// if ( $file =~ /^\./ );

- if ( $depname eq $file ) { # Unchanged .. should be a .h
+ if ( ! ( ( $depname = $file ) =~ s/\.[cS]$/.o: / ) ) {
$cmd = "\n\t\@touch " . $depname;
$depname =~ s/\.h$/.h: /;
}


- # Slurp it all up. $program can become quite long. Memory starved
- # machines will possibly be better served by putting DEPEND=$(AWK)
- # in the main Makefile.
+ # Slurp it all up. $program can become quite long :-)


open ( FILE, $file ) or die "Can't open $file: $!\n";
- $program = join '', <FILE>;
+ $program = <FILE>;
close FILE;


@@ -63,9 +65,11 @@


# Fill @includes array ( if you don't understand see man perlop,
- # man perlre and the Camel )
-
+ # man perlre and the Camel ). If includes with white space in front
+ # should be processed, uncomment next line and comment out the while
+ # loop.

+# @includes = ( $program =~ /^[ \t]*#\s*include[ \t]*[<"](\S*)[">]/gm );
while ( $program =~ /^([ \t]*)#\s*include[ \t]*[<"](\S*)[">]/gm ) {
next if $1; # we don't want indented includes ?
push @includes, $2;
@@ -88,22 +92,14 @@

# First try relative to current directory

- $rfname = $relpath . $fname;
- if ( -e $rfname ) {
+ if ( -e ( $rfname = $relpath . $fname ) ) {
print $depname unless $hasdep;
$hasdep = 1;
print " \\\n ", $rfname;
- if ( $fname =~ /^\./ ) {
- $fnd = grep ( $rfname eq $_, @ARGV );
- push ( @ARGV, $rfname ) unless $fnd;
- }
- } else {
-
- # It was not relative to current dir
-
+ push ( @ARGV, $rfname ) if ( $fname =~ /^\./ && ! grep ( $rfname eq $_, @ARGV ) );
+ } else { # It was not relative to current dir
foreach $path ( @parray ) {
- $rfname = $path . $fname;
- if ( -e $rfname ) {
+ if ( -e ( $rfname = $path . $fname ) ) {
print $depname unless $hasdep;
$hasdep = 1;
print " \\\n ", $rfname;