Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: how can I speed this up?

by TheoPetersen (Priest)
on Feb 23, 2001 at 22:51 UTC ( [id://60527]=note: print w/replies, xml ) Need Help??


in reply to how can I speed this up?

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://60527]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-18 23:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found