Did some benchmarking today. I really like knowing the most effective way to solve a certain problem and when Corion posted his code above, I got curious. To Corion, I would like to say that this is no "I'm right - you're wrong" kind of thing. I've enjoyed your code (since I love and use eConsole) for a long time, and I really didn't know which of the ways that was most effective, so please don't take this the wrong way.
If someone else have ideas about this please, give it a shot with your own code.
I use directory travering quite often so I would really be glad to be able to use the most effective code in my programs.
Here we go:
use Benchmark; use File::Spec; use File::Find; $t0 = new Benchmark; &t1('C:\\Program'); $t1 = new Benchmark; &t2('C:\\Program'); $t2 = new Benchmark; &t3('C:\\Program'); $t3 = new Benchmark; &t4('C:\\Program'); $t4 = new Benchmark; &t5('C:\\Program'); $t5 = new Benchmark; print "t1: ",timestr(timediff($t1, $t0)),"\n"; print "t2: ",timestr(timediff($t2, $t1)),"\n"; print "t3: ",timestr(timediff($t3, $t2)),"\n"; print "t4: ",timestr(timediff($t4, $t3)),"\n"; print "t5: ",timestr(timediff($t5, $t4)),"\n"; # Opens a dirhandle to read files, another to read sub-dirs and # recursive calls itself foreach subdir it finds sub t1 { my $Dir = shift; opendir(DIR, $Dir) || die "Can't opendir $Dir: $!"; my @Files = grep { /.txt/ && -f "$Dir/$_" } readdir(DIR); closedir DIR; opendir(DIR, $Dir) || die "Can't opendir $Dir: $!"; my @Dirs = grep { /^[^.].*/ && -d "$Dir/$_" } readdir(DIR); closedir DIR; foreach $file (@Files) { print $Dir."-".$file."\n"; } foreach $SubDir (@Dirs) { &t1(join("\\",$Dir,$SubDir)); } }; # Opens a dirhandle to read files, rewinds to read sub-dirs and # recursive calls itself foreach subdir it finds sub t2 { my $Dir = shift; opendir(DIR, $Dir) || die "Can't opendir $Dir: $!"; my @Files = grep { /.txt/ && -f "$Dir/$_" } readdir(DIR); rewinddir(DIR); my @Dirs = grep { /^[^.].*/ && -d "$Dir/$_" } readdir(DIR); closedir DIR; foreach $file (@Files) { print $Dir."-".$file."\n"; } foreach $SubDir (@Dirs) { &t2(join("\\",$Dir,$SubDir)); } }; # Opens a dirhandle to read all directory contents and # recursive calls itself foreach subdir it finds # Uses File::Spec, which makes it portable sub t3 { my ($Dir) = shift; my ($entry,@direntries,$fullpath); opendir( DIR, $Dir ) or die "Can't opendir $Dir: $!"; @direntries = readdir( DIR ) or die "Error reading $Dir : $!\n"; closedir DIR; foreach $entry (@direntries) { next if $entry =~ /^\.\.?$/; $fullpath = File::Spec->catfile( $Dir, $entry ); if (-d $fullpath ) { &t3($fullpath); } elsif ( -f $fullpath && $entry =~ /.txt/) { print $Dir."-".$entry."\n"; } } }; # Opens a dirhandle to read all directory contents and # recursive calls itself foreach subdir it finds sub t4 { my ($Dir) = shift; my ($entry,@direntries,$fullpath); opendir( DIR, $Dir ) or die "Can't opendir $Dir: $!"; @direntries = readdir( DIR ) or die "Error reading $Dir : $!\n"; closedir DIR; foreach $entry (@direntries) { next if $entry =~ /^\.\.?$/; $fullpath = join("\\",$Dir,$entry); if (-d $fullpath ) { &t4($fullpath); } elsif ( -f $fullpath && $entry =~ /.txt/) { print $Dir."-".$entry."\n"; } } }; # Uses File::Find (whatever it does...) sub t5 { my ($Dir) = shift; find(\&found, $Dir); } sub found { /.txt/ && print $File::Find::dir."-".$_."\n"; }
This test was run on a Pentiun 233 with 128Mb RAM, Windows 2000, FAT32 filesystem
C:\\Program holds 13477 files in 1206 folders of which 137 matches *.txt

t1: 27 wallclock secs ( 8.40 usr + 16.76 sys = 25.17 CPU)
t2: 24 wallclock secs ( 7.69 usr + 15.57 sys = 23.26 CPU)
t3: 47 wallclock secs (20.30 usr + 23.85 sys = 44.15 CPU)
t4: 36 wallclock secs (11.04 usr + 23.33 sys = 34.37 CPU)
t5: 30 wallclock secs (11.12 usr + 18.02 sys = 29.13 CPU)


/brother t0mas

In reply to RE: RE: RE: Descending through directories by t0mas
in thread Getting a List of Files Via Glob by Zoogie

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.