2016-03-20 6 views
2

Können Sie mir bitte sagen, warum zweiter Code zweimal schneller läuft als der erste Code (6 Sek. Und 11 Sek.) (In allen PHP-Versionen)? Der Grund ist für die Verwendung von Funktionen oder die Verwendung von globalen oder irgendetwas anderes und warum? Ich möchte diesen Fehler in anderem Skript verhindern, aber ich weiß nicht, was genau mein Fehler ist.Welcher Teil braucht mehr Zeit, Funktion oder global?

Ich führe dieses Skript mit Online-Tools, aber haben das gleiche Ergebnis.

Profil erster Code: enter image description here erster Code:

for ($i = 1; $i < 2500; ++$i) { 
    $pen[$i] = $i * (3 * $i - 1)/2; 
} 
function pentagonal($num) { 
    global $pen; 
    return $pen[$num]; 
} 
function is_pentagonal($c) { 
    $x = (1+sqrt(1+24*$c))/(6); 
    if ($x == (int)$x) { 
     return true; 
    } else { 
     return false; 
    } 
} 
for ($i = 2; ; ++$i) { 
    for ($j = 1; $j < $i ; ++$j) { 
     $pi = pentagonal($i); // Here is the difference 
     $pj = pentagonal($j); // Here is the difference 
     if (is_pentagonal($pi + $pj, $pen)) { 
      if (is_pentagonal(abs($pi - $pj), $pen)) { 
       $difference = $pi - $pj; 
       break 2; 
      } 
     } 
    } 
} 
echo $i.' '.$j.' '.$difference."\n"; 

zweiter Code (nur Funktion zu entfernen und den Wert direkt aus dem Array erhalten):

for ($i = 1; $i < 2500; ++$i) { 
     $pen[$i] = $i * (3 * $i - 1)/2; 
    } 
// function pentagonal($num) { 
//  global $pen; 
//  return $pen[$num]; 
// } 
    function is_pentagonal($c) { 
     $x = (1+sqrt(1+24*$c))/(6); 
     if ($x == (int)$x) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
    for ($i = 2; ; ++$i) { 
     for ($j = 1; $j < $i ; ++$j) { 
      $pi = $pen[$i]; // Here is the difference 
      $pj = $pen[$j]; // Here is the difference 
      if (is_pentagonal($pi + $pj, $pen)) { 
       if (is_pentagonal(abs($pi - $pj), $pen)) { 
        $difference = $pi - $pj; 
        break 2; 
       } 
      } 
     } 
    } 
    echo $i.' '.$j.' '.$difference."\n"; 

Antwort

3

Eine Lookup einer Variablen, globaler oder anders in dynamischen Sprachen wird normalerweise als eine Tabellensuche implementiert (entweder eine Hash-Suche oder ein Offset). Das ist sehr schnell. Ein Funktionsaufruf ist immer "teuer" ... Es gibt eine bestimmte Menge an Setup- und Teardown-Code, der ausgeführt werden muss, und dies kann zu vielen tausend Maschinencode-Anweisungen führen. Dies ist im Vergleich langsam.

Wie dem auch sei, es wäre töricht, alle Funktionsaufrufe durch direkten variablen Zugriff in einem größeren System zu ersetzen. Wenn Ihr Problem vollständig im obigen Code ausgedrückt wird, dann ja, greifen Sie direkt auf die Variablen zu, UND VERWENDEN SIE DEN CODE, WENN SIE BEENDET HABEN.

Wenn dies Teil eines größeren Systems ist, verwenden Sie Funktionen. Es macht Testen, Debugging, statische Analyse, Profiling, alles, ... viel, viel einfacher. Selbst wenn die erste Variante des Codes doppelt so schnell ist wie die zweite, wird sie im Rauschen von allem, was gerade passiert, verloren gehen, besonders wenn ein IO auftritt.

UPDATE: Sie können Ihre Funktion etwas effizienter machen, indem es als ...

exprimierenden
function is_pentagonal($c) { 
    $x = (1+sqrt(1+24*$c))/(6); 
    return $x == (int)$x; 

} 

... da dies die Schaffung lexikalische Bereiche vermeiden (oder was auch immer sie in PHP genannt werden).