Phoenix.pm: Best Methods on Win32

Michael Friedman friedman at highwire.stanford.edu
Mon Nov 10 21:16:54 CST 2003


Scott T,

One other thing you might want to do with this is to compress the two 
readdir() calls into a single call. No matter how much you do in 
straight code, it'll be faster than going back to disk. (or, hopefully, 
disk cache. I've never used perl on Windows, so I couldn't tell you if 
it caches properly or not.)

So instead of this:
> 	my @pathSubdirs = grep {!/^\./ && -d "$localRoot\\$_"} readdir(ROOT);
> 	rewinddir (ROOT);
> 	my @pathFiles = grep {-f "$localRoot\\$_"} readdir(ROOT);

Just get the directory listing once:
	my @nodesInThisPath = readdir(ROOT);
	my @pathSubdirs = grep {!/^\./ && -d "$localRoot\\$_"} 
@nodesInThisPath;
	my @pathFiles = grep {-f "$localRoot\\$_"} @nodesInThisPath;

Although, you're still doing a file metadata lookup on each file 
twice...
I believe grep() is optimized in some ways, but you could avoid a lot 
of the file lookups by making your own loop through the nodes in the 
directory:

	my @nodesInThisPath = readdir(ROOT);
	foreach my $node (@nodesInThisPath)
	{
		if ($node =~ m/^\.+/o)
		{	# ignore . and ..
			next;
		}
		stat("$localRoot\\$_");
		push(@pathSubdirs, "$localRoot\\$_") if -d _;
		push(@pathFiles, "$localRoot\\$_") if -f _;
	}

There. Now you read the dir once and test each file once (with stat and 
the special '_' filemetadatahandle). Have I optimized it into 
unreadability yet?

Have fun!
-- Mike

On Monday, November 10, 2003, at 05:11  PM, Scott Thompson wrote:
> Here's the "final" version I got working.  FYI, the output is 
> "designed" to
> be dumped into a CSV file for review in Microsoft Excel.
>
> Comments and suggestions definitely welcome.
>
> ------------------------------>8  Cut 8<------------------------------
> #!perl -w
> use strict;
>
> # Global variables...
> my $pathDepth = 0;
> my $pathRoot = $ARGV[0] ? $ARGV[0] : "C:\\Program Files";
> my $pathMax = $ARGV[1] ? $ARGV[1] : 50;
>
> # Main code section...
> procDir($pathRoot);
>
> # Function code section...
> sub procDir {
> 	my $localRoot = shift;
> 	opendir (ROOT, $localRoot) || die "Cannot open directory $pathRoot: 
> $!\n";
> 	my @pathSubdirs = grep {!/^\./ && -d "$localRoot\\$_"} readdir(ROOT);
> 	rewinddir (ROOT);
> 	my @pathFiles = grep {-f "$localRoot\\$_"} readdir(ROOT);
> 	closedir (ROOT);
>
> 	foreach my $pathFile (@pathFiles) {
> 		if (length("$localRoot\\$pathFile") > $pathMax) {
> 			print "\"$localRoot\\$pathFile\"," . 
> length("$localRoot\\$pathFile") .
> "\n";
> 		}
> 	}
> 	foreach my $pathSubdir (@pathSubdirs) {
> 		$pathDepth++;
> 		procDir("$localRoot\\$pathSubdir");
> 		$pathDepth--;
> 	}
> }
> ------------------------------>8  Cut 8<------------------------------
>
> Scott
>
---------------------------------------------------------------------
Michael Friedman                  HighWire Press, Stanford Southwest
Phone: 480-456-0880                                   Tempe, Arizona
FAX:   270-721-8034                  <friedman at highwire.stanford.edu>
---------------------------------------------------------------------




More information about the Phoenix-pm mailing list