[英]Optimization of prime number code
This is my code in python for calculation of sum of prime numbers less than a given number. 这是我在python中的代码,用于计算小于给定数字的素数之和。
What more can I do to optimize it? 我还能做些什么来优化它?
import math
primes = [2,] #primes store the prime numbers
for i in xrange(3,20000,2): #i is the test number
x = math.sqrt(i)
isprime = True
for j in primes: #j is the devider. only primes are used as deviders
if j <= x:
if i%j == 0:
isprime = False
break
if isprime:
primes.append(i,)
print sum (primes,)
You can use a different algorithm called the Sieve of Eratosthenes which will be faster but take more memory. 您可以使用一种名为Sieve of Eratosthenes的不同算法,它会更快但需要更多内存。 Keep an array of flags, signifying whether each number is a prime or not, and for each new prime set it to zero for all multiples of that prime.
保留一组标志,表示每个数字是否为素数,并且对于每个新素数集,它对于该素数的所有倍数都为零。
N = 10000
# initialize an array of flags
is_prime = [1 for num in xrange(N)]
is_prime[0] = 0 # this is because indexing starts at zero
is_prime[1] = 0 # one is not a prime, but don't mark all of its multiples!
def set_prime(num):
"num is a prime; set all of its multiples in is_prime to zero"
for x in xrange(num*2, N, num):
is_prime[x] = 0
# iterate over all integers up to N and update the is_prime array accordingly
for num in xrange(N):
if is_prime[num] == 1:
set_prime(num)
primes = [num for num in xrange(N) if is_prime[num]]
You can actually do this for pretty large N if you use an efficient bit array, such as in this example (scroll down on the page and you'll find a Sieve of Eratosthenes example). 如果你使用一个有效的位数组,你实际上可以为相当大的N做这个,例如在这个例子中 (在页面上向下滚动,你会找到一个Sieve of Eratosthenes的例子)。
Another thing you could optimize is move the sqrt
computation outside the inner loop. 您可以优化的另一件事是将
sqrt
计算移到内部循环之外。 After all, i
stays constant through it, so there's no need to recompute sqrt(i)
every time. 毕竟,
i
通过它保持不变,所以没有必要每次重新计算sqrt(i)
。
primes = primes + (i,)
is very expensive. primes = primes + (i,)
非常昂贵。 It copies every element on every pass of the loop, converting your elegant dynamic programming solution into an O(N 2 ) algorithm. 它复制循环每次传递的每个元素,将优雅的动态编程解决方案转换为O(N 2 )算法。 Use lists instead:
改为使用列表:
primes = [2]
...
primes.append(i)
Also, exit the loop early after passing sqrt(i). 另外,在传递sqrt(i)之后提前退出循环。 And, since you are guaranteed to pass sqrt(i) before running off the end of the list of primes, update the list in-place rather than storing
isprime
for later consumption: 并且,由于保证在运行素数列表的末尾之前传递sqrt(i),因此就地更新列表而不是存储
isprime
以供以后使用:
...
if j > math.sqrt(i):
primes.append(i)
break
if i%j == 0:
break
...
Finally, though this has nothing to do with performance, it is more Pythonic to use range instead of while: 最后,尽管这与性能无关,但使用范围而不是while时更加Pythonic:
for i in range(3, 10000, 2):
...
Just another code without using any imports: 只是另一个代码而不使用任何导入:
#This will check n, if it is prime, it will return n, if not, it will return 0
def get_primes(n):
if n < 2:
return 0
i = 2
while True:
if i * i > n:
return n
if n % i == 0:
return 0
i += 1
#this will sum up every prime number up to n
def sum_primes(n):
if n < 2:
return 0
i, s = 2, 0
while i < n:
s += get_primes(i)
i += 1
return s
n = 1000000
print sum_primes(n)
EDIT: removed some silliness while under influence 编辑:在受到影响时删除了一些愚蠢
All brute-force type algorithms for finding prime numbers, no matter how efficient, will become drastically expensive as the upper bound increases. 所有用于查找素数的强力型算法,无论效率如何,随着上限的增加将变得非常昂贵。 A heuristic approach to testing for primeness can actually save a lot of computation.
测试素数的启发式方法实际上可以节省大量计算。 Established divisibility rules can eliminate most non-primes "at-a-glance".
既定的可分性规则可以“一目了然”地消除大多数非素数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.