0

I'm using PyCharm community 2018. I'm trying to find the sum of prime numbers from 1 to two million and this is my code.

primes = [x for x in range (1,2000000) if all (x%y!=0 for y in range (2,x))]
total = 0
for x in primes:
    total = total + x
print (total)

It's been 20 minutes and I've still got no output. Do you have any suggestions to make it run faster or is my method wrong?

Riptide
  • 326
  • 2
  • 9
  • 2
    Did you try it on a smaller range first? – Dan Jul 18 '18 at 14:42
  • 3
    Possible duplicate of [Fastest way to list all primes below N](https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n) – modesitt Jul 18 '18 at 14:43
  • But also, yes your algorithm does not look efficient. Looks to be O(n^2) to me. So that's going to be in the trillions of operations for your range. Your `in range (2,x)` only need to go to `x**0.5` but then you have to calc a lot of square roots. Here is a more efficient alternative https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes – Dan Jul 18 '18 at 14:46

3 Answers3

2

This is most likely because your method to find primes is inefficient and your range is too large.

Your algorithm is a brute force way of finding prime numbers and it's time complexity is O(n²). If you time your algorithm for smaller numbers you will see that as you increase n, time taken does not increase linearly, but is in fact quadratic.

+--------+---------------+
|   n    | time(in sec)  |
+--------+---------------+
| 1000   |  0.007979     |
| 2000   |  0.038865     |
| 5000   |  0.137037     |
| 10000  |  0.499688     |
| 20000  |  1.892315     |
| 50000  |  10.29843     |
| 100000 |  1374.101     |
| ...    |  ...          |
+--------+---------------+

I would suggest you to take a look at Sieve of Eratosthenes. You will find many implementations of it in whichever language you want if you search for this.

sP_
  • 1,323
  • 1
  • 13
  • 27
  • 2
    Even though this is good insight, consider posting this as comments in the future. Recoomanding documentation in answers is bad practice. – scharette Jul 18 '18 at 14:46
  • I see. I will consider this next time. Thank you. – sP_ Jul 18 '18 at 14:48
  • Recommending documentation is not bad practice per se, but answers that are merely composed of links to external resources and not much else are. – anothernode Jul 18 '18 at 14:48
  • I've added some detail, I realize it doesn't automatically make it a good answer but tried to explain why it was not a good algorithm for larger values. – sP_ Jul 18 '18 at 15:11
1

I'd recommend using multiprocessing to speed up your code

from multiprocessing import Pool
def find_prime(n):
    #code to determine prime number here
    #return 0 if it is not prime or the number if it is

pool=Pool()
total=sum(pool.map(find_prime,range(1,2000000))
0

Your code is correct. There are lots of ways to get all prime numbers and you are using the most basic definition, and that's why your code is slow. You can refer to this post (There are lots of ways to get all prime numbers and you are using the most basic definition, and that's why your code is slow. You can refer to this post Fastest way to list all primes below N to ) for more advanced and efficient ways to calculate prime numbers and that should speed up your code a lot. Though you will need to learn and understand lots of mathematical principles and details.

TYZ
  • 6,636
  • 4
  • 19
  • 44