OK I was wrong. Checking every prime is way slower than a sieve. My mistake was comparing my optimized code against a slower larger sieve. There is a trade off of speed for size. The sieves that use a set of primes are maybe 2x faster than this sieve code but use much more storage per prime stored. This uses 1 bit per prime where python ints are much larger. Usually the bit array is about 1/5 the size.
I decided to use a bitarray() sieve of Eratosthenes from a program I wrote earlier and then use the 6k-1 prime_sum code I used before. The big advantages are; much faster sieve generator and a very very fast prime check. p[n] just checks a bit for 1 or 0 instead of a long drawn out prime check. This code is 6 times faster than my previous prime_sum(). This is not faster than the set() of prime numbers but it is able to do 4GB lists of primes.
To answer the original question: The sieve is too large using ints and Yes the prints take a long time. Imagine printing out 7,930,427 sums! I just printed the first few. Enough to prove Goldbach right without waiting for a while.
Here are the two outputs for large numbers:
My previous code:
$ python simple_goldbach.py
Total Time: 0.041585
Avg Testrun Time: 0.002079
30,000 has 602 representation(s)
Please enter an even number greater than 3> 12345678
12,345,678 has 71,169 representation(s) took 1.613520
Please enter an even number greater than 3> 4000000000
4,000,000,000 has 7,930,427 representation(s) took 498.131707
Please enter an even number greater than 3>
And the new sieve code:
$ python sieve_goldbach.py
Made new sieve 1,000,000,000 in 4.366924
Total Time: 0.012563
Avg Testrun Time: 0.000628
30,000 has 602 representation(s)
Please enter an even number greater than 3> 12345678
12,345,678 has 71,169 representation(s)
prime_sum took: 0.195684
31 + 12,345,647 = 12,345,678
41 + 12,345,637 = 12,345,678
97 + 12,345,581 = 12,345,678
101 + 12,345,577 = 12,345,678
Please enter an even number greater than 3> 4000000000
1,000,000,000 is less than 4,000,000,000 making new sieve
Made new sieve 4,000,000,000 in 19.151368
4,000,000,000 has 7,930,427 representation(s)
prime_sum took: 77.966109
89 + 3,999,999,911 = 4,000,000,000
131 + 3,999,999,869 = 4,000,000,000
239 + 3,999,999,761 = 4,000,000,000
383 + 3,999,999,617 = 4,000,000,000
Please enter an even number greater than 3> 200000000
200,000,000 has 538,290 representation(s)
prime_sum took: 3.153349
37 + 199,999,963 = 200,000,000
43 + 199,999,957 = 200,000,000
97 + 199,999,903 = 200,000,000
181 + 199,999,819 = 200,000,000
Please enter an even number greater than 3>
Here is my faster sieve representation:
from timeit import default_timer
from bitarray import bitarray
global primes
def make_sieve(size):
"""Create a sieve of Eratosthenes up to the given size."""
s_start = default_timer()
limit = int(1 + size**0.5) + 2
p = bitarray(size+2) # One bit per value
p.setall(True)
p[0:2] = False # Clear zero and one
p[4::2] = False # Clear multiples of 2
p[9::3] = False # Clear multiples of 3
for i in range(5, limit, 6): # Process only numbers of the form 6k-1 and 6k+1
h = i + 2 # 6k+1
if p[i]: # If 6k-1 is prime
p[i*i::2 * i] = False # Clear multiples of 6k-1
if p[h]: # If 6k+1 is prime
p[h*h::2 * h] = False # Clear multiples of 6k+1
p = p[:size]
s_stop = default_timer()
print(f" Made new sieve {len(p):,} in {s_stop - s_start:4f}")
#return [i for i in range(2,size+1) if p[i]] # to return list of primes
return p
def prime_sum(n):
global primes
if len(primes) < n:
print(f"{len(primes):,} is less than {n:,} making new sieve")
primes = make_sieve(n)
sums = []
if n&1 or n<4:
print("Only even numbers greater than 3")
return sums
if n == 4:
return [[2,2]]
if primes[n-3]:
sums += [[3,n-3]]
for k6 in range(5,n//2+1,6): # only check 6k-1 and 6k+1
if primes[k6] and primes[n-k6]:
sums += [[k6,n-k6]]
if primes[k6+2] and primes[n-(k6+2)]:
sums += [[k6+2,n-(k6+2)]]
return sums
primes = make_sieve(10**9)
test_runs = 20
total = 0
test_num = 30000
for _ in range(test_runs):
out = []
start = default_timer()
a = prime_sum(test_num)
stop = default_timer()
total += (stop - start)
print('Total Time: {:4f}'.format(total))
print('Avg Testrun Time: {:4f}'.format(total / test_runs))
N = test_num
goldbach_sums = prime_sum(N)
print(f"{N:,} has {len(goldbach_sums):,} representation(s)")
while True:
N=-1
while N<4 or N&1:
N = int(input("Please enter an even number greater than 3> "))
start = default_timer()
goldbach_sums = prime_sum(N)
stop = default_timer()
print(f"{N:,} has {len(goldbach_sums):,} representation(s)")
print('prime_sum took: {:4f}'.format(stop-start))
print(*[f"{x:,} + {y:,} = {N:,}" for [x,y] in goldbach_sums[:4]],sep='\n')