1

I have made some code that calculates prime numbers (Nothing special I know) and as expected it slows down the bigger the number, I know it is impossible to make it the same speed no matter the number but I am sure I could improve it's speed, I just don't know how...

import time
number = 1000000001
count = 0
start = time.time()
while number > 1000000000 and number < 10000000000000:
    for i in range(1, round(number/2 + 1)):
        if (number / i).is_integer():
            count += 1
        if count > 1:
            break
    if count < 2:
        print(str(number) + ' prime')
    number = number + 1
    count = 0
end = time.time()
print(end - start)
Qwertykey
  • 21
  • 4
  • 5
    Possible duplicate of [Fastest way to list all primes below N](https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n) – mrhallak Jun 11 '17 at 11:01
  • 3
    First of all Python is slow. Secondly, there are lots of very advanced and difficult to understand algorithms for finding primes. This is not a topic for 5min talk. – freakish Jun 11 '17 at 11:02
  • 3
    Use a [sieve](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) – khelwood Jun 11 '17 at 11:12
  • @khelwood according to http://primesieve.org/, even that would take about a day - 25h - to run, for the 10T limit. trial division would run for years, or maybe centuries, who knows. – Will Ness Jul 11 '17 at 14:01

1 Answers1

4

Several things:

  • you do not have to check from 1, but 3, 5 and all odd numbers;
  • you do not have to check until n/2, but you can stop at sqrt(n);
  • do not use division, since then you work with floating points, but use % to check modulo;
  • you only have to check odd numbers (or two); and
  • you can omit the greater than check in the while loop, since the number only increments.

So an improved version would be:

import time
from math import sqrt # import square root

start = time.time()

for number in range(1000000001,10000000000000,2): # use for, hops of 2
    for i in range(3, int(sqrt(number))+1,2): # check 3, 5,... up to sqrt(n)
        if number % i == 0: # use modulo checks instead of floating point
            break
    else: # use a for-else structure for faster ending
        print(str(number) + ' prime')
    count = 0
end = time.time()
print(end - start)

Nevertheless, Python is not designed to get the most out of a CPU. If you really want to code a superoptimized algorithm, you will have to pick a faster (and less convenient) programming language.

Willem Van Onsem
  • 321,217
  • 26
  • 295
  • 405
  • 1
    You can use `for n in range(number, 10000000000000, 2)`. `for` loop is faster than `while` loop. – FJSevilla Jun 11 '17 at 11:14
  • 1
    this is very helpful, i have also noticed if i do not print the primes and instead append them to a list and print of the list when finished it is much faster. – Qwertykey Jun 11 '17 at 14:08