I gather you have a large percentage of "unoccupied" elements in your source data, because based on what you say, the big difference in response time is mainly a matter of whether or not this condition fires (and skips the rest of the loop block):
next if( $options{"unoccupied"} eq "0" && $_[6] eq "unoccupied\n" );
If that doesn't fire, you end up doing four more "if" tests on every iteration, and then deleting an element from an array (which probably doesn't do what you think it does -- check "perldoc -f delete").

So there are ways to reduce the overall amount of work that perl is doing in the loop while still getting things done just as well (or even better). I don't know how much execution time would be saved, but I think the following version is at least a bit cleaner and not any harder to maintain than your original.

As mentioned previously, you haven't shown how you initialize some of the variables in the posted snippet, so I'm going to guess that your "$planets" value was intialized to the number of elements in the "@data" array (i.e. your for loop covers every array element).

Another thing I have to guess about is that elements in @data either have 7 fields (0-6) with the last one having the string "unoccupied", or else they have 9 fields (0-8). If there are more fields than that, then the code below would be inappropriate.

my $dispmode = $options{display} * 2; $dispmode |= $options{coordinate}; # bitwise OR # $dispmode values: 0 == display:0 and coordinate:0 # 1 == display:0 and coordinate:1 # 2 == display:1 and coordinate:0 # 3 == display:1 and coordinate:1 # create a distinct print sub for each mode: # (in the second one, the regex places parens around # the last two comma-delimited fields on the line if # the last field is numeric) my @modesub = ( sub { print $_[0], "<br>\n" }, sub { ($_=$_[0]) =~ s/([^,]*,-?[\d]+)$/($1)/; print "$ +_ <br>\n"}, sub { print "<tr><td>" . join("</td><td>",split /,/, $ +_[0]) . "</td></tr>\n" }, sub { print "<tr><td>" . join("</td><td>",split /,/, $ +_[0], 8) . "</td></tr>\n" } ); for ( @data ) { # the following regex will check if this element of @data has # "unoccupied" following the 6th comma, and nothing thereafter: next if( $options{"unoccupied"} == 0 && /^(?:[^,]*,){6}unoccupied$ +/ ); $modesub[$dispmode]->( $_ ); } @data = (); # added this to get rid of the data # though maybe that doesn't really matter? print "</table>" if($dispmode & 2);
That version does only one "if" test on each loop iteration, economizes the removal of elements from the array (and actually makes the memory available for garbage collection, unlike "delete"), and only uses split when it really has to.

Also, I think that using @data and the field values on each row as lists (rather than always addressing specific array elements by index numbers) could save some time. (It certainly makes the coding easier.)

Still, if the proportion of "unoccupied" rows is extremely large, the process will just take that much longer when all those rows are being printed. Maybe you need to allow for paging the output (e.g. 100 rows per page, or whatever)?

(updated to fix punctuation, and to change from "while (@data)" to "for (@data)" -- I think doing "shift" on each iteration in a while loop is more work than necessary.)

Another update: I noticed your links to the code and data after I posted this, and was glad to see that I had guessed right. ;-) One extra little detail: it looks like your data file might contain blank lines, but you don't seem to be checking for that -- I don't know if this might be part of the "delay" problem, but just to be sensible, you should read from the file like this:

@data = grep /\S/, <DAT>; # skip blank lines chomp @data; # remove newline chars
Final update (sorry...): I tighted up the second "modesub" so it only adds parens if the line ends with digits. Also, I deleted a couple lines of code that had been superceded by updates, rather than just commenting them out.

In reply to Re: Printing data from a file in various ways by graff
in thread Printing data from a file in various ways by oomwrtu

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.