in reply to Re: Iteration speed
in thread Iteration speed

__UPDATE____

dear all

I've started a 'profile' on one of my biggest files (15 chains!) and here's the most telling results:

%Time    Sec.     #calls   sec/call  F  name
17.79 1043.2695  10727535   0.000097     PDB::Bonds::notClose
14.88  872.6432  14509596   0.000060     PDB::Writer::numberFormat
10.52  616.7291  14509596   0.000043     PDB::Bond::dist
 6.89  403.8085  14509597   0.000028     PDB::Writer::pad_left
 6.40  375.5808        1  375.580791  ?  HighPDB::parse
 6.39  374.5854  14509596   0.000026     PDB::Writer::pad_right
 5.54  325.1066  43586508   0.000007     UNIVERSAL::isa
 4.89  286.5572  1881489   0.000152     PDB::Bond::new
 3.49  204.5796  18291657   0.000011     PDB::Atom::x
 3.42  200.8238  18291657   0.000011     PDB::Atom::y
 3.23  189.6586  18291657   0.000010     PDB::Atom::z
 3.14  184.3266  1881489   0.000098     PDB::Bond::isHydphb
 3.14  184.2096  1880381   0.000098     PDB::Bond::isElcsta
 2.24  131.0808        1  131.080769     WhatIf::doWhatif
 1.91  111.7546  10730691   0.000010     PDB::Atom::resName
The code for the first three subroutines are shown here:

sub notClose{ my $self=shift; my ($a1,$a2,$m)=@_; my %hash = %$a2; my $cutoff = $lengths{$a1->resName} + 7 + $hash{'r'}; my $dist = PDB::Bond->dist($a1->x,$hash{'x'},$a1->y,$hash{'y'},$a1 +->z,$hash{'z'}); my $value = $dist<$cutoff ? 0 : 1; return $value; } sub dist{my $self=shift if UNIVERSAL::isa($_[0] => __PACKAGE__); my ($x1, $x2, $y1, $y2, $z1, $z2)=@_; return numberFormat(sqrt ( ($x1 - $x2)**2 + ($y1 - $y2)**2 + ($z1 - $z2)**2 ), 1,2); } sub numberFormat{ my( $number, $whole, $frac ) = @_; return pad_left('0',$whole,'0').'.'.pad_right('0',$frac,'0')if $nu +mber == 0; return pad_left($number,$whole,'0') unless $number =~ /\./ || $fra +c; my ($left,$right); ($left,$right) = split /\./, $number; $left = pad_left($left, $whole, '0'); if(defined $right){ $right = pad_right( substr($right,0,$frac), $frac, '0' ); return "$left\.$right"; }else{ $right = pad_right( '0', $frac, '0'); return "$left\.$right"; } } sub pad_left { my $self=shift if UNIVERSAL::isa($_[0] => __PACKAGE__); my ($item, $size, $padding) = @_; my $newItem = $item; $padding = ' ' unless defined $padding; while( length $newItem < $size ) { $newItem = "$padding$newItem"; } return $newItem; } sub pad_right { my $self=shift if UNIVERSAL::isa($_[0] => __PACKAGE__); my ($item, $size, $padding) = @_; my $newItem = $item; $padding = ' ' unless defined $padding; while( length $newItem < $size ) { $newItem .= $padding; } return $newItem; }

I had totally forgotten that I use numberFormat to manipulate the result of the sqrt function. (This is essential for the DB) I'm now going to move this to the DB part, so that it only gets called when adding 'real' bonds to the DB.

I'm also going to remove the UNIVERSAL::isa calls, and just try to ASSUME $self whenever I can.

Thanks for all the help, and I'm still investigating mr. Delauney.

Cheers
Sam

Replies are listed 'Best First'.
Re^3: Iteration speed
by BrowserUk (Patriarch) on Jun 16, 2004 at 20:35 UTC

    FWIW. Here is the code I mentioned earlier. It just completed a run looking for pairs of atoms that are within .01 units of each other.

    The input was 1,000,000 atom coordinates randomly generated in file that looks like this

    atom000001 : 0119.110 0443.939 0146.027 atom000002 : -217.194 -175.476 -200.134 atom000003 : 0202.789 -383.911 0183.319 atom000004 : -459.869 0354.187 -421.509 atom000005 : 0446.625 0097.504 0243.835

    It found 308,822 pairs within the requisite distance of one another (from the 1,000,000,000,000 possibles) in just under 7 hours on 2Ghz machine.

    Whether the technique is adaptable to your application I'm not sure.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon