For yucks, I tested three variations (in separate scripts) of replacing one string with another in a text file -- that contained ~16,100 lines -- replacing 190 occurrences of the target string. The three variations are shown below. Time::HiRes ( gettimeofday tv_interval ) was used in the body of each script to time each run -- and each script was run 5 times intermixed with the others. Run on a laptop running MS Windows XP and ActiveState Perl 5.8.7 build 815.
I think what's going on is that for variations 1 and 3, Perl is "slurping" the input file into an array, performing the substitutions on the array elements, and then writing out the array elements. For variation 2, there's no array involved. It's simply "read a line, perform the substitution on that line, write a line". And I think the explanation for the time differences between 1 and 3 is that there is a certain amount of overhead associated with the map function -- that's not present with the for loop.
And looking at this from the perspective of "Perl Best Practices" by Damian Conway (well worth reading)...
(1) Note the use of indirect file handle variables instead of bareword file handles (page 202 :-).
(2) Not shown in the variation examples but used in the test scripts is the 3 argument form of open (page 207) as in the following.
open (my $outfile, '>', 'testout.txt') or die "could not open outfile $!";
(3) Shown in variation 2 is avoid modification of "$_" (page 85).
(4) Demonstrated by the slight time advantage of variation 2 over variation 3, "use while (<>), not for (<>)" for input loops (page 211).
So other than the problematic "chomp", your original while loop is best from both a runtime and a Perl Best Practices perspective.
Regards,
... Dewey
Variation 1 - map - in one statement
print {$outfile} map { s/$oldval/$newval/g; $_ } <$infile>;
Variation 2 - while loop "line at a time"
while (my $line = <$infile>) {
$line =~ s/$oldval/$newval/g;
print {$outfile} $line;
}
Variation 3 - for loop - with no intermediate variable
for (<$infile>) {
$_ =~ s/$oldval/$newval/g;
print {$outfile} $_;
}
The elapsed times are as follows.
Variation 1 - map - in one statement
Elapsed time: 0.186486
Elapsed time: 0.192088
Elapsed time: 0.180844
Elapsed time: 0.179598
Elapsed time: 0.214627
Variation 2 - while loop "line at a time"
Elapsed time: 0.077885
Elapsed time: 0.078739
Elapsed time: 0.073292
Elapsed time: 0.076311
Elapsed time: 0.085483
Variation 3 - for loop - with no intermediate variable
Elapsed time: 0.109979
Elapsed time: 0.119098
Elapsed time: 0.110375
Elapsed time: 0.111947
Elapsed time: 0.117261
_______________________________________________ Perl-Win32-Users mailing list [email protected] To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
