Optimierung einer funktion. Habt ihr noch tips?

MC Breit

Erfahrenes Mitglied
Hi!
Ich habe eine funktion geschrieben, die eine MessengerRNA (mRNA) in eine Peptid-Kette übersetzt.
Die funktion soll dabei berücksichtigen, das jeder 3er schritt nach dem start triplet AUG manuel ausgwertet wird, sprich das noch keine vorhandene zeichenfolge verglichen wird wie "AGG => Pro" sondern das diese Individual zusammengesetzt werden.
Dabei will ich natürlich möglichst schnell sein, was bedeutet das jede milisekunde zählt.
Da mir mittlerweile nichtsmehr einfällt, was ich noch verbessern könnte, damit es schneller wird wollte ich einmal fragen, ob ihr noch ideen habt wie ich das ganze schneller machen könnte.

Was weshalb wie ist:
1. while() anstatt for(), wurde mit beidem getestet und while ist im test schneller gewesen, obwohl grundsetzlich die selben operationen durchgeführt werden.
$mrna{0},{1}.., da dies schneller ist als immer $chr = $mrna{x} vorher zuzuweisen, der direktzugriff auf einen teil des strings scheint also schneller zu sein als das zuweisen des teilstrings zum vergleichen.
if/else anstatt switch/case, ebenfalls schneller.

Hier mal mein code:

PHP:
<?php
  function mrna_to_pepchain1($mrna)
  {
    //Find the start-codon and fetch the tail..
    $mrna = strstr($mrna, 'AUG');
    $max = floor(strlen($mrna)/3)-1;
    $chain = '';

    $i = -1;
    while($i<$max)
    {
      $i++;
      $mrna = substr($mrna, 3);
      if($mrna{0} == 'G')
      {
        if($mrna{1} == 'G')
        {
          $chain .= 'Gly-';
        }
        elseif($mrna{1} == 'A')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            $chain .= 'Glu-';
          }
          else
          {
            $chain .= 'Asp-';
          }
        }
        elseif($mrna{1} == 'U')
        {
          $chain .= 'Val-';
        }
        else
        {
          $chain .= 'Ala-';
        }
      }
      elseif($mrna{0} == 'A')
      {
        if($mrna{1} == 'G')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            $chain .= 'Arg-';
          }
          else
          {
            $chain .= 'Ser-';
          }
        }
        elseif($mrna{1} == 'A')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            $chain .= 'Lys-';
          }
          else
          {
            $chain .= 'Asn-';
          }
        }
        elseif($mrna{1} == 'U')
        {
          if($mrna{2} == 'G')
          {
            $chain .= 'Met-';
          }
          else
          {
            $chain .= 'Ile-';
          }
        }
        else
        {
          $chain .= 'Thr-';
        }
      }
      elseif($mrna{0} == 'U')
      {
        if($mrna{1} == 'G')
        {
          if($mrna{2} == 'G')
          {
            $chain .= 'Trp-';
          }
          elseif($mrna{2} == 'A')
          {
            break;
          }
          else
          {
            $chain .= 'Cys-';
          }
        }
        elseif($mrna{1} == 'A')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            break;
          }
          else
          {
            $chain .= 'Tyr-';
          }
        }
        elseif($mrna{1} == 'U')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            $chain .= 'Leu-';
          }
          else
          {
           $chain .= 'Phe-';
          }
        }
        else
        {
          $chain .= 'Ser-';
        }
      }
      else
      {
        if($mrna{1} == 'G')
        {
          $chain .= 'Arg-';
        }
        elseif($mrna{1} == 'A')
        {
          if($mrna{2} == 'G' || $mrna{2} == 'A')
          {
            $chain .= 'Gln-';
          }
          else
          {
            $chain .= 'His-';
          }
        }
        elseif($mrna{1} == 'U')
        {
          $chain .= 'Leu-';
        }
        else
        {
          $chain .= 'Pro-';
        }
      }
    }
    
    return substr($chain, 0, -1);
  }
?>

Zum testen habe ich folgendes gemacht:
PHP:
<?php
$test_mrna =
'GACUAUGAAAACACAGUCUGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACU
CAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGGUACUAUAUGGAUUGC
AGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCC
UUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAG
CUACGGGAAUCAAUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCA
GCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCC
UCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUA
GUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCC
CCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAUAUA
UGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGC
UCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAUCAAUCCCCCCCUUACGGCUACAGGUACUCA
AGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAU
GGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGG
AUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAC
GGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUA
CUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAUCAAUC
CCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACG
GCUACAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCC
CUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUAC
AGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACUUAGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCC
CUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUAC
AGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAU
CAAUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCC
UUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUCCCCCCCUU
ACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGG
UACUAUAUGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGA
UUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAUAUAUGGAUUGCAG
CUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUU
ACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAUCAAUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUA
UGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGC
UCCCCCCCUUACGAGGAUCGAUUCGAUCCCUCCCCCCCUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUC
CCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGGCUACAGGU
ACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAAGGUAC
UAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAUCAAUCCCCCCCUUAC
GGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAUUGC
AGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUAGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGGCUA
CAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUACAGGUACUCAA
GGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAUCAAUCCCCCC
CUUACGGCUACAGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUAGGAUUGCAGCUCCCCCCCUUACGGCUAC
AGGUACUCAAGGUACUAUAUGGAUUGCAGCUCCCCCCCUUACGAGGAUCGAUUCGAUCCCUACGACGAAGCUACGGGAAU
CAAUCAAAUCGGGUUCUUACGGGAAUCAAUCAAAUCGGGUCGAUCCACGA';
$test_mrna = str_replace(array("\r","\n"), '', $test_mrna);

echo '----- BioTranscription::mrna_to_pepchain_1 -----'."\n";
echo 'Start:  '.$start=mktime()."\n";
for($i=0;$i<10000;$i++)
{
  $chain = mrna_to_pepchain1($test_mrna)."\n"; //mRNA, from 5' to 3'
}
echo $chain;
echo 'Finish: '.$finish=mktime()."\n";
echo 'Result: '.$result=$finish-$start." sekunden\n";
?>
Braucht bei mir mit Athlon 1700+ und PHP 4.3 im moment 22 sekunden.

Wenn ihr irgendwelche vorschläge habt wie ich es noch schneller machen kann, dann bitte her damit! Danke..
 
Zuletzt bearbeitet:
Mmmh...ich muss gestehen, mein Bio-Unterricht ist schon ein Weilchen her, aber wozu dient diese Schleife?:
Code:
for($i=0;$i<10000;$i++)
{
  $chain = mrna_to_pepchain1($test_mrna)."\n"; //mRNA, from 5' to 3'
}

...wenn man es nur einmal laufen lässt, ist das Ergebnis, soweit ich sehe, das Gleiche.... das wäre also ein guter Ansatzpunkt um Zeit zu sparen(braucht dann < 1sec)
 
Die Schleife dürfte nur dafür da sein, die Zeitmessung ein bisschen zu vereinfachen, indem die Funktion öfter ausgeführt wird.
 
Abgesehen davon, dass ich absolut keine Ahnung habe wovon ihr redet :P

Wenn dus schnell haben willst, dann nimm doch c++ her?
Stellt sich halt die Frage für was du es so schnell haben willst?


PS: Du könntest ja auch mehrere einzelne Ifs machen und nicht diese tiefe Verschachtelung. Dadurch würde er vielleicht schneller die While verlassen bzw. mal gucken was im Durchschnitt öffter vorkommt und das an den Anfang setzten.
 
Zuletzt bearbeitet von einem Moderator:
Ja, das mit dem sortieren ist eine gute idee, das mit dem Ifs wegmachen wird nich viel bringen glaub ich, ich hatte schonmal vorher probiert coutinue; einzubringen um die schleifen früher zu beenden, das hat aber nix gebracht..

Hast du denn ne idee wo ich informationen darüber bekomme welche zeichen am öftesten im genetischen code vorkommen von reihnfolgen und so?
Weil ich als nicht Biologe werde das so woll nicht rausfinden :-/

Edit: Zu der sache mit C++: Dann könnte ich es auch in asm schreiben ;)
 
Sind switch-case Anweisungen langsamer als if..elseif..elseif? Bei so vielen Verschachtelungen haette ich mir das überlegt.. rein aus Übersichtsgründen schon, aber ob es schneller is weiss ich nich %)

Was mir bei solcher Textdurchsucherei noch einfaellt:

preg_match() .. ist das evtl schneller? Ich meine mit Regex durchprüfen?

So in dieser Form :
PHP:
if ( preg_match("/^GAG/",$mrna) )  $chain .= 'Glu-';

elseif ( pregmatch("/^GAA/",$mrna)) )  $chain .= 'Glu-';

// elseif ( ...) ...
// elseif ( ...) ...

Aber wieder keine Ahnung ob da schneller ist :) Evtl kann da noch jemand was dazu sagen .
Alles nur so Spontangedanken :D

Gruß Frank

EDIT: Wenn ich so drueber nachdenke, isses wohl kaum schneller, weil du ja mit dem Startbuchstaben schon einschraenkst, welche Tripel noch in Frage kommen.. Bei der Variante oben werden jedesmal alle druchsucht.. also haengt es nur davon ab welche (evtl öfter vorkommenden Fälle) weiter oben in der Prüfkette stehen.
Hmm.... :confused: :-) :eek: :suspekt: :-(
 
Zuletzt bearbeitet:
Zurück