Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Can you help profile this?

by Tanktalus (Canon)
on Dec 08, 2011 at 23:34 UTC ( [id://942520]=note: print w/replies, xml ) Need Help??


in reply to Can you help profile this?

First thing's first. If you have sets embedded in your list, keep them as sets. What you're doing is nearly the same thing as pointer arithmetic in C, and is bad for many of the same reasons. ww mentioned an AoA, but as a question. I'll make it a statement: it should be an array of references. Personally, I'm a bit more partial to AoH, as it allows me to use names for keys to make sense of the inner data. An AoA would look like:

@in = ( [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ], [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 ], # ... );
but we still don't know what any of the numbers mean without more context. An AoH usually would take up a lot more memory, but would give the context implicitly:
@in = ( { user => 'Fighter2', id => 936570, xp => 34, writeups => 11, ... }, );
You can get hashes to take a lot less memory if you can define "default" values that cover most cases, reducing most of the hashes down to only unique values, at a slight cost to code complexity. I'll assume that's not an option (it rarely is, in my experience).

Once you do this, you would have $in[$i][12] or $in[$i]{attn} instead of $in[$i+12] Your outer for loop would be a simple for my $i (0..$#in) (you would want to go through the indexes, and the last one is the last index, which is what $# gives you). You wouldn't be creating an @Attn the length of your original array, but 1/14th the size, which would help both memory usage and speed. Also, your inner arrays would be arbitrary lengths - so if you regularly have less than 13 items in a set, you simply would not allocate the extra memory. And, should you need more than 14 items in a set, you can now handle that, kind of.

Here's a first crack:

#!/usr/bin/perl #Initialization my @in=( [...], [...], ); my $MaxAgc0 = "1.15503129132678e-005"; # MaxAgc0 is a constant #Interpolation if (@in) { for my $i (0..$#in) { my $ptr = $in[$i]; # convenience. # we don't need the first item to be a count of sectors anymor +e. # we also don't need this loop at all. #for my $j (0..$#$ptr) #{ # so we also reduce the numbers here. my $num = $ptr->[11] * $MaxAgc0; push @Attn, $num / $ptr->[9]; #} } for my $i (0..$#in) { push @powers, ($in[$i][$_] - $Attn[$i])/100 for (1..8); } } else { # @in is empty print "\n No data to map for Panda machine. Check if input logfile + is empty"; kill; }
Now, what I'd do from here is pull apart the sets even more. Say something like this:
( { attn => 5, # attenuation? agc => 6, # the MaxAgc0 multiplier sectors => [ all the sectors for this data point in this array ], # etc. }, # repeat for each item. )
I'd also change the output to match everything done above: return a list of arrays:
#!/usr/bin/perl #Initialization my @in=( {...}, {...}, ); my $MaxAgc0 = "1.15503129132678e-005"; # MaxAgc0 is a constant use List::MoreUtils qw(pairwise); #Interpolation if (@in) { my @Attn = map { my $num = $_->{agc} * $MaxAgc0; $num / $_->{attn}; } @in; @powers = pairwise { [ map { ( $a->{sectors}[$_] - $b ) / 100 } for @{$a->{sectors} +} ] } @in, @Attn; } else { # @in is empty print "\n No data to map for Panda machine. Check if input logfile + is empty"; kill; }
Now the return will keep the sectors grouped, there will be no extra data in the output. We can still improve this by getting rid of @Attn altogether:
#Initialization my @in=( {...}, {...}, ); my $MaxAgc0 = "1.15503129132678e-005"; # MaxAgc0 is a constant #Interpolation if (@in) { @powers = map { my $attn = $_->{agc} * $MaxAgc0 / $_->{attn}; [ map { ( $_->{sectors}[$_] - $attn ) / 100 } for @{$_->{secto +rs}} ] } @in; } else { # @in is empty print "\n No data to map for Panda machine. Check if input logfile + is empty"; kill; }
We got rid of a huge amount of wasted memory. That @Attn list was humongous in your code, and we've pared it down to 1/14th and now to a single scalar (which we calculate as we need it, then discard it once no longer needed). And we got rid of unnecessary items in your sets, though, in the interests of readability, I increased the memory usage of the input by making it an AoH's. That's probably a wash, if not slightly bigger now than it was.

Hope that helps.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-26 03:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found