We don't bite newbies here... much PerlMonks

### Optimization Help

 on Aug 01, 2013 at 23:06 UTC Need Help??
jmmitc06 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks:

I am a bioinformatics programmer and I am currently running a very large calculation looking for subgraph isomorphisms. I have optimized it to the best of my abilities (I'm limited to the scale of my rewriting since the underlying objects/modules are used in much of my other code)

Below is a subroutine that currently consumes 74% of the time in my multiday calculation, even when using a cluster with torque. I have tried various different things, but I cannot beat what I have and any improvement would save me considerable time.

```sub equate2
{
my (\$self, \$other, \$mapping) = @_;
foreach my \$row_index (0..\$#\$mapping)
{
return 0 if (grep { \$\$self{Matrix}[\$row_index][\$_] != \$\$other{Matr
+ix}[\$\$mapping[\$row_index]][\$\$mapping[\$_]]); } (0..\$#\$mapping));
}
return 1;
}

I can provide more information if necessary, but in short this subroutine finds if elements of two matrices, i and j determined by a vector: \$mapping.

Any advice and any tips for improving performance would be greatly appreciated. I have tried switching out the grep and foreach with for statements to no avail.

Thanks to all the monks for the help you have given in the past.

Replies are listed 'Best First'.
Re: Optimization Help
by choroba (Bishop) on Aug 01, 2013 at 23:25 UTC
grep iterates over all the numbers from 0 to \$#mapping. Stopping the loop as soon as the first inequality is found might speed the subroutine up, especially if the array is large and inequalities are not very rare. You can use a simple for loop instead:
```for (0 .. \$#mapping) {
return 0 if \$self->{Matrix}[\$row_index][\$_]
!= \$other->{Matrix}[\$mapping->[\$row_index]][\$mapping->[\$_
+]];
}
return 1;

Update: The hash dereference could also take some microseconds if repeated many times. As \$row_index does not change, you can assign the values to variables:

```my \$self_row  = \$self->{Matrix}[\$row_index];
my \$other_row = \$other->{Matrix}[\$mapping->[\$row_index]];
for (0 .. \$#mapping) {
return 0 if \$self_row->[\$_] != \$other_row->[\$mapping->[\$_]];
}
return 1;
لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Optimization Help
by BrowserUk (Pope) on Aug 01, 2013 at 23:24 UTC

Your first problem is that your posted code doesn't compile. You have unbalanced parens and mismatched curlies:

```if (grep { \$\$self{Matrix}[\$row_index][\$_] != \$\$other{Matrix}[\$\$mapping
+[\$row_index]][\$\$mapping[\$_]]); } (0..\$#\$mapping));
(     {
+                            ^  } (             ))

What are the dimensions of your matrices and the mapping array?

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Sorry, I typed it in by hand, here is the correct code ;)

```sub equate2
{
my (\$self, \$other, \$mapping) = @_;
foreach my \$row_index (0..\$#\$mapping)
{
return 0 if (grep { (\$\$self{Matrix}[\$row_index][\$_] != \$\$other{Mat
+rix}[\$\$mapping[\$row_index]][\$\$mapping[\$_]]); } (0..\$#\$mapping));
}
return 1;
}
Oh and all the matrices are 2D and the mapping vector is 1D

Try:

```sub equate2 {
my (\$self, \$other, \$mapping) = @_;
my \$sm = \$self->{Matrix};
my \$om = \$other->{Matrix};
for my \$row ( 0 .. \$#\$mapping ) {
my \$smrow = \$sm->[ \$row ];
my \$omrow = \$om->[ \$mapping->[ \$row ] ];
for my \$col ( 0 .. \$#\$mapping ) {
return 0 if \$smrow->[ \$col ] != \$omrow->[ \$mapping->[ \$col
+ ] ];
}
}
return 1;
}

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1047512]
Approved by BrowserUk
help
Chatterbox?
 [LanX]: leaving bed? weird idea!

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (10)
As of 2018-03-20 11:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When I think of a mole I think of:

Results (250 votes). Check out past polls.

Notices?