the main point in my post was that if you add to your input list a relatively large prime, or the product of a relatively large with some other factors, your performance will fall dramatically. As an example, I took 2**31 - 1 (i.e. 2147483647), a number 280 times smaller than the large number (600851475143) that you use, but much less favorable because it is prime, your code will take not a split second, but several minutes to run (about five minutes on my laptop). Try it for your self to see the problem.
In such a case, the optimization consisting in running the for loop until the square root of the target will provide you with a huge improvement. This optimization, together with the other two that I described, made my code about 5,000 times faster for the same input data.
As a starting point you could just change this line:
to this:for ( my $y = $large_prime_found; $y <= $num;) {
This should already improve considerably the timings. But this calculates the square root of $num many many times.for ( my $y = $large_prime_found; $y <= $num ** .5;) {
It would be better to compute the square root of $num (into, say, $max) outside of the for loop header, i.e. at the beginning of your subroutine and at the place where you modify the value of $num within the for loop, and to use $max within the header of the for loop:
Check that everything still works OK with your new version of the subroutine, I haven't tested these improvements with it, and there may be one or two small things to adjust somewhere else in the code.for ( my $y = $large_prime_found; $y <= $max;) {
In reply to Re^5: Avoid keeping larger lists in Memory
by Laurent_R
in thread Avoid keeping larger lists in Memory
by pr33
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |