for( a=1; a <= 25; a++){
num1 = m[a];
for( b=1; b <= 25; b++){
num2 = m[b];
for( c=1; c <= 25; c++){
num3 = m[c];
for( d=1; d <= 25; d++){
num4 = m[d];
for( e=1; e <= 25; e++){
num5 = m[e];
for( f=1; f <= 25; f++){
num6 = m[f];
for( g=1; g <= 25; g++){
num7 = m[g];
for( h=1; h <= 25; h++){
num8 = m[h];
for( i=1; i <= 25; i++){
num = num1*100000000 + num2*10000000 +
num3* 1000000 + num4* 100000 +
num5* 10000 + num6* 1000 +
num7* 100 + num8* 10 + m[i];
check_prime = 1;
for ( y=2; y <= num/2; y++)
{
if ( num % y == 0 )
check_prime = 0;
}
if ( check_prime != 0 )
{
array[x++] = num;
}
num = 0;
}}}}}}}}}
The above code takes a hell lot of time to finish executing.. In fact it doesn’t even finish executing, What can i do to optimize the loop and speed up the execution?? I am newbie to cpp.
You’re checking 259 = 3,814,697,265,625 numbers whether they’re prime. That’s a lot of prime tests and will always take long. Even in the best case (for performance) when all array entries (in
m) are 0 (never mind that the test considers 0 a prime), so that the trial division loop never runs, it will take hours to run. When all entries ofmare positive, the code as is will run for hundreds or thousands of years, since then each number will be trial-divided by more than 50,000,000 numbers.Looking at the prime check,
the first glaring inefficiency is that the loop continues even after a divisor has been found and the compositeness of
numestablished. Break out of the loop as soon as you know the outcome.In the unfortunate case that all numbers you test are prime, that won’t change a thing, but if all (or almost all, for sufficiently large values of almost) the numbers are composite, it will cut the running time by a factor of at least 5000.
The next thing is that you divide up to
num/2. That is not necessary. Why do you stop atnum/2, and not atnum - 1? Well, because you figured out that the largest proper divisor ofnumcannot be larger thannum/2because if(num >) k > num/2, then2*k > numandnumis not a multiple ofk.That’s good, not everybody sees that.
But you can pursue that train of thought further. If
num/2is a divisor ofnum, that meansnum = 2*(num/2)(using integer division, with the exception ofnum = 3). But thennumis even, and its compositeness was already determined by the division by 2, so the division bynum/2will never be tried if it succeeds.So what’s the next possible candidate for the largest divisor that needs to be considered?
num/3of course. But if that’s a divisor ofnum, thennum = 3*(num/3)(unlessnum < 9) and the division by 3 has already settled the question.Going on, if
k < √numandnum/kis a divisor ofnum, thennum = k*(num/k)and we see thatnumhas a smaller divisor, namelyk(possibly even smaller ones).So the smallest nontrivial divisor of
numis less than or equal to√num. Thus the loop needs only run fory <= √num, ory*y <= num. If no divisor has been found in that range,numis prime.Now the question arises whether to loop
or
The first needs one multiplication for the loop condition in each iteration, the second one computation of the square root outside the loop.
Which is faster?
That depends on the average size of
numand whether many are prime or not (more precisely, on the average size of the smallest prime divisor). Computing a square root takes much longer than a multiplication, to compensate that cost, the loop must run for many iterations (on average) – whether “many” means more than 20, more than 100 or more than 1000, say, depends. Withnumlarger than10^8, as is probably the case here, probably computing the square root is the better choice.Now we have bounded the number of iterations of the trial division loop to
√numwhethernumis composite or prime and reduced the running time by a factor of at least 5000 (assuming that allm[index] > 0, so that alwaysnum >= 10^8) regardless of how many primes are among the tested numbers. If most valuesnumtakes are composites with small prime factors, the reduction factor is much larger, to the extent that normally, the running time is almost completely used for testing primes.Further improvement can be obtained by reducing the number of divisor candidates. If
numis divisible by 4, 6, 8, …, then it is also divisible by 2, sonum % ynever yields 0 for eveny > 2. That means all these divisions are superfluous. By special casing 2 and incrementing the divisor candidate in steps of 2,the number of divisions to perform and the running time is roughly halved (assuming enough bad cases that the work for even numbers is negligible).
Now, whenever
yis a multiple of 3 (other than 3 itself),num % ywill only be computed whennumis not a multiple of 3, so these divisions are also superfluous. You can eliminate them by also special-casing 3 and lettingyrun through only the odd numbers that are not divisible by 3 (start withy = 5, increment by 2 and 4 alternatingly). That chops off roughly a third of the remaining work (if enough bad cases are present).Continuing that elimination process, we need only divide
numby the primes not exceeding√numto find whether it’s prime or not.So usually it would be a good idea to find the primes not exceeding the square root of the largest
numyou’ll check, store them in an array and loopUnless the largest value
numcan take is small enough, if, for example, you’ll always havenum < 2^31, then you should find the primes to that limit in a bit-sieve so that you can look up whethernumis prime in constant time (a sieve of 2^31 bits takes 256 MB, if you only have flags for the odd numbers [needs special-casing to check whethernumis even], you only need 128 MB to check the primality of numbers< 2^31in constant time, further reduction of required space for the sieve is possible).So far for the prime test itself.
If the
marray contains numbers divisible by 2 or by 5, it may be worthwhile to reorder the loops, have the loop forithe outermost, and skip the inner loops ifm[i]is divisible by 2 or by 5 – all the other numbers are multiplied by powers of 10 before adding, so thennumwould be a multiple of 2 resp. 5 and not prime.But, despite all that, it will still take long to run the code. Nine nested loops reek of a wrong design.
What is it that you try to do? Maybe we can help finding the correct design.