Wow, there's nothing quite like FORTRAN in Perl. :) My sympathies, I have to do a lot of this too.

First of all, let me say that if your goal is to make the Perl code run as fast as the FORTRAN code, then stick with FORTRAN. If your goal is to get away from FORTRAN's miserable excuses for text handling, then welcome to Perl and you're on the right track.

As for what could be better: the first thing that jumped out to me was to replace the loop in decode with combinations of unpack and map. The only tricky bit is that you have to build the template string for unpack on the fly, since we don't know the number of values in advance. If I read the code correctly, something like this would work:

sub decode { my ($record, $nt, $val_missing) = @_; my $template = ('A5' x $nt) . ('A2' x $nt); my @values = unpack($template, $record); my @fractions = @values[0 .. $nt-1]; my @exponents = @values[$nt .. $#values];
unpack did the equivalent of all the substr calls in one go, so that should save some time. Look at perlman:perlop if it's not clear how the string is being constructed.

At this point you could process the two arrays in parallel in a for loop. Note that the C-style loop is appropriate here since we are using the index value in multiple arrays:

@values = (); for (my $i = 0; $i < @fractions; $i++) { if ( == 0 and $exponents[$i] == 99) { $values[$i] = $val_missing; } else { $fractions[$i] *= 10.**(-5); if (($exponents[$i] % 2) == 0) { $exponents[$i] = 10.**($exponents[$i]/2); } else { $exponents[$i] = 10.**(-($exponents[$i]+1)/2); } $values[$i] = $fractions[$i] * $exponents[$i]; } } return @values; }
I had thought there might be a faster way to do this with map, but all of my answers seem contrived and convoluted, especially considering how much conditional code there is per item. If you're learning your way around Perl, try getting this or something similar going first, then look at a more idiomatic approach.

Is it possible to change the format of the data? If so, a simpler algorithm could greatly improve the speed.


In reply to Re: how can I speed this up? by TheoPetersen
in thread how can I speed this up? by rbi

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.