关于python:如何提高这个程序的效率?

how to increase the efficiency of this program?

本问题已经有最佳答案,请猛点这里访问。

以下程序(在函数prime内)的运行时间为110.726383227秒。

如果我运行相同的程序而不将其包装在函数(prime)中,则运行时间为222.006502634秒。

我将它包装在一个函数中,从而显著提高了性能。

还有没有可能提高这个项目的效率?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This is a program to find sum of prime numbers till 2 billion

def prime():
import time
start_time = time.clock()

num = 2
j=1
tot_sum = 0

for num in xrange(2,2000000):
    count = 0
    for j in xrange(1,int(num**0.5)+1): # checking from 1 to sqrt(n)+1
        if(num % j == 0):
            count = count+1

    if(count == 1):
        tot_sum = tot_sum + num

print"total sum is %d" % tot_sum

print time.clock() - start_time,"seconds"


如果你想在没有外部libs的情况下解决它,你可以做一些明显的改进:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def prime():
    import time
    start_time = time.clock()

    tot_sum = 2

    for num in xrange( 3, 2000000, 2 ):
            isPrime = True
            for j in xrange(3, int( num ** 0.5 ) + 1, 2 ):
                if( num % j == 0 ):
                    isPrime = False
                    break

            if isPrime:
                tot_sum = tot_sum + num

    print"total sum is %d" % tot_sum

    print time.clock() - start_time,"seconds"

prime()

不检查大于2个偶数,如果发现除数,不检查所有除数。您的原始代码在172.924809秒内在我的机器上运行,而我的代码在8.492169秒内运行。

如果允许使用外部libs,我建议使用gmpy2

1
2
3
4
5
6
7
8
9
10
def prime():
    from gmpy2 import is_prime
    import time
    start_time = time.clock()

    print"total sum is %d" % (sum(filter(is_prime, xrange(3,2000000,2)))+2)

    print time.clock() - start_time,"seconds"

prime()

这只需要1.691812秒


这可能与Python解析变量的方式有关。大致上,当您输入一个函数时,python会创建一个新的名称空间,它基本上映射到该函数的所有局部变量。然后,Python可以使用名称空间来确定程序员正在访问的所有变量的值。变量名称解析的顺序如下:

  • 查找本地命名空间中的变量名
  • 在全局命名空间中查找变量名
  • 在python的内置程序中查找名称。

执行查找可能代价高昂,而在Python中,一个通用的性能提示就是仅出于这个原因使用局部变量:至少,它将避免执行两次查找而不是一次查找。另外,更新的python编译器似乎也在进行额外的优化,以删除对本地名称空间的单个查找,但只将变量视为即时值。

测试这种优化是否仅仅因为名称空间查找而发生的一个好方法可能是(除了我不知道的其他优化)将所有逻辑包装在一个函数中,但将所有使用的变量设置为全局变量。如果一切都变慢了,您可能会猜测是命名空间查找花费了太多时间。