Nick
Nick

Reputation: 9051

Is Generator supposed to be lazy?

I tried to calculate the nth prime number in PHP:

function is_prime($n) {
    if ($n <= 1) {
        return false;
    } elseif ($n <= 3) {
        return true;
    } elseif (($n % 2 == 0) ||  ($n % 3 == 0)) {
        return false;
    }

    $i = 5;
    while ($i * $i <= $n) {
        if (($n % $i == 0) || ($n % ($i + 2) == 0)) {
            return false;
            $i = $i + 6;
        }
    }
    return true;
}

function prime_gen() {
    for($x=0; $x< PHP_INT_MAX; $x++) {
        if(is_prime($x)){
            yield $x;
        }
    }
}


function nth_prime($n) {
    for($i=0; $i<=$n; $i++) {
        $ps = iterator_to_array(prime_gen());
    }

    return $ps[$n-1];
}

echo nth_prime(9);

I got Maximum execution time of 3 seconds exceeded error. Is generator supposed to be lazy? Shouldn't I write for($x=0; $x< PHP_INT_MAX; $x++)?

Upvotes: 0

Views: 79

Answers (1)

deceze
deceze

Reputation: 522402

iterator_to_array iterates the entire generator until it is exhausted and gives you the result in an array. The generator is "lazy", but you're explicitly breaking that and are forcing the evaluation of the entire generator. Moreover, you're doing that in a loop. You pretty much just need to get rid of iterator_to_array. Better solution:

$nth = 0;
foreach (prime_gen() as $prime) {
    if (++$nth >= $n) {
        break;
    }
}

return $prime;

Upvotes: 2

Related Questions