CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Optimizing this function

 



LeoF
Novice

Sep 8, 2000, 8:25 AM

Post #1 of 5 (306 views)
Optimizing this function Can't Post

Hello Everyone,

Could someone be so kind as to tell me if the following code could be done more efficiently?

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

@group_names = ("group1", "group2", "group3", "group4","group5");
#
@groups = (["01", "11", "22"],
["02", "44", "66"],
["07", "15", "53"],
["13", "27", "39"],
["17", "23", "41"]);
#
sub which_group {
my ($thisone) = @_;
$x = 0;
foreach $item (@groups) {
for (@$item) {
if ($_ == $thisone) {
return $group_names [$x];
}
}
$x++;
}
} # / which_group</pre><HR></BLOCKQUOTE>

The numbers in @groups are assigned in no particular order, could change, and they need have a 0 before a single digit number as is defined somewhere else in the script.

Since there will always be only a few groups I wonder if there could be a way of just finding the index of the group that $thisone belongs to, and use it to get the string from @groups_names, without having to loop through every item. Maybe using a different data structure?.

I know that using return from inside a loop is not very elegant to say the least, but if I use "last" it'll only escape from the inner loop and continue with the outer, is there a way to break out of both loops at once so I can move the return to the end of the function?

Any comments and suggestions would be very appreciated, thanks in advance for your cooperation.

Be Well


japhy
Enthusiast

Sep 7, 2000, 10:49 PM

Post #2 of 5 (306 views)
Re: Optimizing this function [In reply to] Can't Post

I think you'd be better off with a data structure like so:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


%num_to_name = ();
@num_to_name{qw(
01 11 22
02 44 66
07 15 53
13 27 39
17 23 41
)} = (
('group 1') x 3,
('group 2') x 3,
('group 3') x 3,
('group 4') x 3,
('group 5') x 3,
);
</pre><HR></BLOCKQUOTE>

That may LOOK hideous, but think of the time you save by doing:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


$name = $num_to_name{$group_number};
</pre><HR></BLOCKQUOTE>

Whew. Effortless, no?

And as for return()ing from a for-loop, there's nothing wrong with that at all, but if you DO want to last() out of an outer block, you want to use block labels:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


OUTER: for $i (1 .. 10) {
for $j ($i .. 10) {
if ($X == $i**$j) { last OUTER }
}
}
</pre><HR></BLOCKQUOTE>

------------------
Jeff "japhy" Pinyan -- accomplished author, consultant, hacker, and teacher



fashimpaur
User / Moderator

Sep 8, 2000, 12:28 PM

Post #3 of 5 (306 views)
Re: Optimizing this function [In reply to] Can't Post

LeoF,

I worked out this solution:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>



%groups = ( group1 => ["01", "11", "22"],
group2 => ["02", "44", "66"],
group3 => ["07", "15", "53"],
group4 => ["13", "27", "39"],
group5 => ["17", "23", "41"]);

#
my %assoc = getAssociations();;

$i = 0;

foreach (0..1000) {
$x = $_;
$x= substr($i,length($i) - 2) if (length ($i)>2);
$x = '0'.$i if (length($x) < 2);
which_group($x);
};

exit;

sub getAssociations {
my %hash;
while (($key,$value) =each %groups){
foreach (@{$value}){
$hash{$_} = $key;
}
}
return %hash;
}

sub which_group {
my $thisone = shift;
return ($assoc{$thisone})?$assoc{$thisone}:'none';
} # / which_group

</pre><HR></BLOCKQUOTE>

The time for 1000 iterations of your subroutine called in a foreach() was 370 msec
and the time for one call to the get associations and 1000 calls of which_group
took 90msec. If you are only using a few values that will not change, use the method
Japhy suggested. If it is a dynamically changing, use my alternative.

HTH,

Dennis


LeoF
Novice

Sep 8, 2000, 1:23 PM

Post #4 of 5 (306 views)
Re: Optimizing this function [In reply to] Can't Post

Thanks again Jeff, you understood exactly what I meant:

$name = $num_to_name{$group_number};

Is just as effortless as I was thinking about, I knew there had to be a way to do it, just that I didn't know how to make such a data structure, and the "x 3" takes care of the repetitiveness I was trying to avoid in the first place.

Thanks for clarifying about returning from inside a loop, I'll keep that in mind for the future.

Thanks a lot Jeff for your time and attention, I appreciate it.

Be Well


LeoF
Novice

Sep 8, 2000, 1:29 PM

Post #5 of 5 (306 views)
Re: Optimizing this function [In reply to] Can't Post

Thanks a lot Dennis for taking the tiem to write that code, I'll save it for future reference, but as you say, my application adapts better to Jeff's method.

Thanks for your time and atention, I appreciate it.

Be Well

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives