Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Why is this so slow? Message-ID: <10653@jpl-devvax.JPL.NASA.GOV> Date: 6 Dec 90 20:35:41 GMT References: <1990Dec6.194412.9132@cunixf.cc.columbia.edu> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 96 In article <1990Dec6.194412.9132@cunixf.cc.columbia.edu> ben@cunixf.cc.columbia.edu (Ben Fried) writes: : I've written a filter in perl to do printer page counting for DEC ln03 : printers. Right now it seems to be working fine, but it runs abysmally : slowly. The vast majority of time is taken up in the following loop: : : mainloop: : while(read(STDIN, $_, 2048)) { : foreach $i ($[..length($_)) { : $num_to_print = $i; : $oc=$c; : $c = substr($_, $i, 1); : if ($tektronixmode) { : if (($c eq "\f") && ($oc eq "\033")) { : $pageno++; : } : } else { : if ($ascii_mode) { : if ($c eq "\n") { : $lineno++; : if ($lineno == $lines_per_page) { : $lineno = 0; : $pageno++; : } : } : } else { : if ($c eq "\f") { : $lineno = 0; : $pageno++; : } : } : } : : if ($pageno >= $max_pages) { : $debug && print STDERR "aborted at page $pageno\n"; : print STDOUT substr($_, $[, $num_to_print); : last mainloop; : } : : } : : print STDOUT; : } That looks like a reasonable C solution, though even in C I'd avoid testing all those conditionals on every character. Here's an equivalent in Perl. if ($tektronixmode) { $/ = "\f"; while (<>) { $pageno++ if /\033\f$/; &blowup, last if $pageno > $max_pages; print; } } elsif ($ascii_mode) { $max_lines = $max_pages * $lines_per_page; while (<>) { &blowup, last if $. > $max_lines; print; } } else { $/ = "\f"; while (<>) { &blowup, last if $. > $max_pages; } } sub blowup { $debug && print STDERR "aborted at page $pageno\n"; } I'm not sure that $ascii_mode is a valid distinction, however. Perhaps you really mean: if ($tektronixmode) { $/ = "\f"; while (<>) { $pageno++ if /\033\f$/; &blowup, last if $pageno > $max_pages; print; } } else { while (<>) { $lineno++; $pageno++, $lineno = 0 if /\f/; $pageno++, $lineno = 0 if $lineno > $lines_per_page; &blowup, last if $pageno > $max_pages; print; } } Or something like that... Larry