2015-06-19 22 views
9

Tak więc napisałem skrypt, w którym można wprowadzić liczbę, a program znajdzie najwyższą liczbę pierwszą w tym zakresie. Problem polega na tym, że w PHP obliczenia te są bardzo powolne przy większych liczbach, w porównaniu do mojej wersji JavaScript, która jest dokładnie taka sama, ale znacznie szybsza.Obliczenia matematyczne PHP naprawdę powolne

//Here Is the PHP code: 
<form> 
    <input type="text" name="input"> 
</form> 

<?php 
    $input = $_GET['input']; 

    function Prime($num) 
    { 
     if($num < 2) 
      return false; 

     for ($i = 2; $i < $num; $i++) 
     { 
      if($num % $i == 0) 
       return false; 
     } 
     return true; 
    } 

    for($i = $input; $i > 0; $i--) 
    { 
     if(Prime($i)) 
      echo $i; 

     if(Prime($i)) 
      exit(); 
    } 
} 

Oto wariant JavaScript:

<html> 
    <script> 
     var input = prompt("Enter The Number"); 

     function Prime(num) { 
      for (var i = 2; i < num; i++) { 
       if(num % i == 0) { 
        return false; 
       } 
      } 
      return true; 
     } 

     for(var i = input; i > 0; i--){ 
      if(Prime(i)){ 
       document.write(i); 
      } 
      if(Prime(i)){ 
       exit(); 
       p.thisbreaksthecode(); 
      } 
     } 
    </script> 
</html> 

Dla kodu JavaScript, znalezienie najwyższy w prime 99999999 trwa 1,5 sekundy. Jednak w PHP zajmuje to aż 20 sekund. Biorąc pod uwagę fakt, że oprócz składni, oba kody są dokładnie identyczne. To mówi mi, że coś jest nie tak. Jaki może być powód tej powolnej prędkości obliczeniowej? Czy to ze względu na sposób działania PHP? Jak mogę to naprawić?

+3

Pierwsze pytanie: Dlaczego dwa razy obliczasz zalewkę? Drugie pytanie: Czy czytasz o "profilowaniu"? – Sven

+0

Porównujesz różne środowiska wykonawcze i programowanie serwera/klienta. Wydaje mi się, że jakaś kompilacja w samą porę wystartuje, gdy twój silnik javascript zostanie uruchomiony. – collapsar

+0

Wykonuje mniej niż 2 sekundy, aby wykonać na 3v4l.org, jeśli nie obliczysz dwukrotnie liczby pierwszej; i to bez optymalizacji kodu w żaden sposób - http://3v4l.org/hdXNM/perf#tabs –

Odpowiedz

0

Wyraźnie robisz coś złego w sposobie, w jaki go prowadzisz.

wykonałem go (php -f calc.php) i zajęło niewiele:

<?php 
$input = 9999999; 

function Prime($num) { 
    if($num < 2) return false; 
    for ($i = 2; $i < $num; $i++) { 
     if($num%$i==0) 
      return false; 
    } 
    return true; 
} 

$start = microtime(true); 
for($i = $input; $i > 0; $i--){ 
    if (Prime($i)){ 
     echo $i . PHP_EOL; 
     echo (microtime(true) - $start) . PHP_EOL; 
     exit; 
    } 
} 

zajmuje mniej niż sekundę, aby wykonać: 0.94304203987122

Teraz po zmianie $i++ do ++$i to idzie w dół do: +0,67830395698547 (Pre-inkrementacja jest szybszy niż post-przyrostu PHP)

+0

9999999 to 9999999, myślę, że miałeś na myśli 99999999 – zefram

+0

Tak, 9 z ośmioma dziewiątkami – user4757174

4

Jaki może być powód tej powolnej prędkości obliczeniowej? Czy to ze względu na sposób działania PHP?

Prawdopodobnie; PHP nie (obecnie) wykonuje optymalizacji JIT, więc takie ciasne pętle będą bardzo bolesne.

Jak mogę to naprawić?

przez podniesienie lepszy algorytm:

// https://en.wikipedia.org/wiki/Primality_test#PHP_implementation 
function isPrime($n) 
{ 
    if ($n <= 3) { 
     return $n > 1; 
    } else if ($n % 2 === 0 || $n % 3 === 0) { 
     return false; 
    } else { 
     for ($i = 5; $i * $i <= $n; $i += 6) { 
      if ($n % $i === 0 || $n % ($i + 2) === 0) { 
       return false; 
      } 
     } 
     return true; 
    } 
} 

Dla wejścia prądowego działa 500x szybciej.

+0

Wow, algorytm to wszystko. Dzięki, nie spodziewałem się tak dużego wzrostu prędkości. – user4757174

Powiązane problemy