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