http://qs1969.pair.com?node_id=762285

Angharad has asked for the wisdom of the Perl Monks concerning the following question:

I have two data files that I'm working with right now. They are fairly large, but I'll just show snippets of both for the purposes of this post. File 1 is as follows:
Y 39 1jpeA Y 40 1jpeA L 41 1jpeA Y 42 1jpeA R 43 1jpeA K 44 1jpeA Q 45 1jpeA L 72 1gtiA G 73 1gtiA R 74 1gtiA S 75 1gtiA L 76 1gtiA etc ...1jpe,0,TYR,A,42
and then file 2
1jpe,0,CYS,A,109 1jpe,0,CYS,A,103 1jpe,0,TYR,A,42 1jpe,0,ASP,A,68 1jpe,0,TYR,A,71 1jpe,0,PHE,A,70 etc ...
For each item (referred to as, for example '1jpeA' in file 1 and '1jpe' and 'A' in file 2 (you can get other items called 1jpeB, 1jpeC etc so we need to obtain what is called the chain letter (A) as well as the '1jpeA' code), search for entries that are equivalent (that is share the same item code and number (the numbers of interest are found in column 2 for file 1 and column 5 for file 2) and then print off these instances into a different file. so, for the example above, the result is
1jpeA 42
As both files have an entry for 1jpeA sharing the number 42, but share no other entries - i.e.
Y 42 1jpeA (from file 1) 1jpe,0,TYR,A,42 (from file 2)
I've written a perl script to do this task. It works but its very slow and I was wondering if anyone had any tips on how I might speed it up. Heres the code
#!/usr/local/bin/perl use strict; use warnings; my $aa; my $num; my $str; my $hashlookup; my $pdb; my $csanum; my $chain; my $resfile = shift; my $csafile = shift; my %hash; open(RESFILE, "$resfile") or die "unable to open $resfile: $!\n"; open(CSAFILE, "$csafile") or die "unable to open $csafile: $!\n"; #my @resarray = <RESFILE>; #close(RESFILE); my @csaarray = <CSAFILE>; close(CSAFILE); #for (my $i = 0; $i < @resarray; $i++) while(<RESFILE>) { #my @array = split /\s+/, $resarray[$i]; my @array = split /\s+/, $_; # lets do a test print $aa = $array[0]; $num = $array[1]; $str = $array[2]; $str = substr($str, 0, 5); #print "test $str $num $aa\n"; for (my $j = 0; $j < @csaarray; $j++) { my @fields = split /\,/, $csaarray[$j]; $pdb = $fields[0]; $csanum = $fields[4]; $chain = $fields[3]; #print "test2 $pdb $csanum $chain\n"; my $pdbchain = "$pdb" . "$chain"; if("$str" eq "$pdbchain") { if (!$hash{$str}{$csanum}) { $hash{$str}{$csanum}++; print "$str $csanum\n"; } } } }
Thanks in advance :)