When I was working with the Sieve of Eratosthenes, a Sieve for finding all prime number below x, the input number. I have to keep track of an array that contains either 0 or 1. The size of the array equals to the input number.
The code before using string:
function esprime($limit){
$sqrtlimit = sqrt($limit);
$range = 1;
while($range<$limit){
$i[$range] = 1;
$range+=2;
}
$n = 2;
while($n < $sqrtlimit){
if ($i[$n]){
$sqn = $n*$n;
$k = $sqn;
$i[$k]=0;
while($k<=$limit){
$k += $n;
$i[$k]=0;
}
}
++$n;
}
$n = 1;
while($n<$limit){
if($i[$n]) $primes[] = $n;
$n+=2;
}
if($limit>=2) $primes[0] = 2;
return $primes;
}
This is extremely memory exhausting. 32MB of memory is all used up while trying to find all prime numbers up to 500,000.
32MB = 33,554,432 bytes
Without running the function, the script uses 4,786,192 bytes of memory. So 27 MB is used for creating a size 250,000 array(all the even ones are dropped).
Is there any way to fix this problem? This array have to be created instantly so you can't just drop values out from it. Doesn't that mean it's impossible for this to work?
There is really nothing we can do with array in this case.
Don't despair! we can use string!
Because the value of the array can be represent by a character, the key of the array can be represent by the position of the character in the string.
so instead of this code
$range = 1;
while($range<$limit){
$i[$range] = 1;
$range+=2;
}
I uses this:
$range = 0;
while($range<$limit){
$i .= '11';
$range+=2;
}
The good thing about this is I don't need to change my entire script, because each character inside a string can be accessed like an array by it's position:
$i = '30000'
echo $i[0];//3
Using the string method, I successfully made it run up to 5,000,000 with out a problem.
I don't know things like this will ever occur to a PHP programmer, because this is useful only when you are having limited memory but also having an array with huge amount of data that can be represent by a limited amount of keys.
Robert Mark Howting made it even better :)
It's much more efficient. Except this time we have to have a case to output the even prime 2.
You can see it in the end of this script.
BTW, I'm also working on Sieve of Atkin. Strange I can't make it faster than Sieve of Eratosthenes.
Bookmark/Search this post with:
Good example
Nice :) Good example!
Have a nice day,
Anders Törnkvist
Post new comment