Jenda Krynicky <[EMAIL PROTECTED]> wrote:
: 
: From: WC -Sx- Jones 
: > 
: > undef $/;  # Slurp;
: > 
: > foreach $target (@ARGV) {
: >   @lines = ();
: > 
: >   open (HTML_FILE, "<$target") or die "owie";
: >   @lines = split(/\n/, <HTML_FILE>);
: > 
: >   print "In $target - Seen: ". ($#lines + 1) ." lines...\n";
: > }
: > 
: > __END__
: 
: Rather inefficient.
: First you slurp the file and then you split it? Why?
: 
: You could do it like this instead :
: 
: foreach $target (@ARGV) {
:   open (HTML_FILE, "<$target") or die "owie";
:   my @lines = <HTML_FILE>;
: 
:   print "In $target - Seen: ". scalar(@lines) ." lines...\n";
: }
: 
: Even shorter, slightly more efficient, but still very memory hungry.
: (The scalar() is not necessary, thanks to the dots @lines would be in 
: scalar context anyway. And since the @lines is lexicalized into the 
: loop I do not have to explicitely clear it.)
: 
: Since you don't actually need the lines you might also do it like 
: this:
: 
: foreach $target (@ARGV) {
:   open (HTML_FILE, "<$target") or die "owie";
:   () = <HTML_FILE>;
: 
:   print "In $target - Seen: ". $. ." lines...\n";
: }
: 
: I'd be worried though that Perl might load the whole file and 
: construct the list anyway so I'd rather use
: 
: foreach $target (@ARGV) {
:   open (HTML_FILE, "<$target") or die "owie";
:   1 while <HTML_FILE>;
: 
:   print "In $target - Seen: ". $. ." lines...\n";
: }

    Sorry, Jenda, these last two don't work because $. does not reset
after each file in @ARGV is opened. It accumulates. $. shows total
lines counted across all files. You need to add an explicit
"close HTML_FILE;" to get it working right. (See perlvar)


    According to the FAQ (perlfaq5), this is a fairly efficient line
counter. More efficiency could be gained by declaring $count, $buffer,
and $target outside the foreach loop and playing with the buffer size.
I assume slurping the file and doing the count would be faster also.

foreach my $target (@ARGV) {
    my $count = 0;
    open FH, $target or die qq|Can't open "$target": $!|;
    while ( sysread FH, my $buffer, 4096 ) {
        $count += ($buffer =~ tr/\n//);
    }

    print "In $target - Seen: $count lines...\n";
}


    My personal preference is a sub routine. Though I think it fails
the "not iterating through the file" requirement here. I wonder why
the OP doesn't want to do that? [shrug]

sub line_count {

    my( $file_handle, $buffer_size ) = @_;
    $buffer_size ||= 4096;

    my( $buffer, $count );

    while ( sysread $file_handle, $buffer, $buffer_size ) {
        $count += ( $buffer =~ tr/\n// );
    }

    return $count;
}


HTH,

Charles K. Clarkson
-- 
Head Bottle Washer,
Clarkson Energy Homes, Inc.
Mobile Home Specialists
254 968-8328


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to