http://qs321.pair.com?node_id=18209


in reply to WARNING t0mas wrote BAD CODE
in thread Odd file rename

Hi merlyn. I did some benchmarking to see how opendir/readdir/closedir performed compared to File::Find.
use Benchmark; use File::Find; my $dirSep = $^O eq "MSWin32" ? "\\" : "/"; my $fileCounter=0; $t0 = new Benchmark; &test1('Program'); $t1 = new Benchmark; print $fileCounter . "\n"; $fileCounter=0; $t2 = new Benchmark; &test2('Program'); $t3 = new Benchmark; print $fileCounter . "\n"; print "test1: ",timestr(timediff($t1, $t0)),"\n"; print "test2: ",timestr(timediff($t3, $t2)),"\n"; sub test1 { my $Dir = shift; opendir(DIR, $Dir) || die "Can't opendir $Dir: $!"; my @Files = grep { /\.txt$/ && -f "$Dir$dirSep$_" } readdir( +DIR); rewinddir(DIR); my @Dirs = grep { /^[^.].*/ && -d "$Dir$dirSep$_" && ! -l "$ +Dir$dirSep$_"} readdir(DIR); closedir DIR; foreach (@Files) { $fileCounter+=1; } foreach $SubDir (@Dirs) { &test1(join($dirSep,$Dir,$SubDir)) +; } }; sub test2 { my ($Dir) = shift; find(\&found, $Dir); } sub found { -f && /\.txt$/ && ($fileCounter+=1); }
The test-machine was a dual boot P233MHz/256RAM. The Program directory is on a FAT32 partition.

On Win2000 the results where:

15085
15085
test1: 52 wallclock secs (17.89 usr + 34.68 sys = 52.57 CPU)
test2: 50 wallclock secs (18.41 usr + 30.94 sys = 49.35 CPU)


On Redhat Linux 6.0 the results where:
15085
15085
test1: 14 wallclock secs ( 2.25 usr + 12.57 sys = 14.82 CPU)
test2: 14 wallclock secs ( 2.86 usr + 10.11 sys = 12.97 CPU)

Pretty even...

When I added a /\.txt/ && to &found and to the @Files = grep {} statement in &test1 the results changed a bit. The more complex regexp (regexp wise), the worse Find::File performed on Win32.
On Win2000 the new results where:

136
136
test1: 30 wallclock secs (10.17 usr + 18.79 sys = 28.95 CPU)
test2: 32 wallclock secs (12.19 usr + 19.76 sys = 31.95 CPU)

On Linux it depended on when the regexp was evaluated. If I put it before -f, it performed better than if I put it after.


I believe that the choise of method depends on the problem faced. My "every-day" environment is Win32 and in my opinion the File::Find has a simple and elegant syntax, but it performs worse than the opendir/readdir/closedir on my main environment.
So until File::Find performs better on Win32, you can call me stupid and cargo-cultist, but I guess I'll stick to opendir/readdir/closedir.
Please note that I don't want to start a war about this, I just wanted to clarify my opinions. I do agree that the code I posted had some issues.

/brother t0mas