Python 如何提高该计划的效率?
以下程序(在函数prime内)的运行时间为110.726383227秒 如果我运行同一个程序而不将其包装在函数(prime)中,那么它的运行时间是222.006502634秒 通过将其包装到函数中,我实现了显著的性能改进 还有没有可能提高这个项目的效率Python 如何提高该计划的效率?,python,optimization,python-2.7,performance,Python,Optimization,Python 2.7,Performance,以下程序(在函数prime内)的运行时间为110.726383227秒 如果我运行同一个程序而不将其包装在函数(prime)中,那么它的运行时间是222.006502634秒 通过将其包装到函数中,我实现了显著的性能改进 还有没有可能提高这个项目的效率 # This is a program to find sum of prime numbers till 2 billion def prime(): import time start_time = time.clock() num =
# 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"
这可能与python解析变量的方式有关。大致上,当您输入一个函数时,python会创建一个新的名称空间,它本质上映射到该函数的所有局部变量。Python然后可以使用名称空间来确定程序员正在访问的所有变量的值。变量名解析的顺序如下:
- 在本地命名空间中查找变量名
- 在全局命名空间中查找变量名
- python内置的查找名称
测试这种优化是否仅仅因为名称空间查找而发生的一个好方法可能是(除了我不知道的其他优化)将所有逻辑封装在一个函数中,但将所有使用的变量都设置为全局变量。如果一切都变慢了,您可能会猜测是名称空间查找占用了这么多时间。如果您想在不使用外部LIB的情况下解决它,您可以做一些明显的改进:
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
:
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秒使用
timeit
模块来测试程序的计时,而不是time.clock()
@hcwhsatimeit
非常好,但是当一次运行需要几分钟时,它是不切实际的。它是为小片段设计的。使用timeit
来计时一次运行是没有用的(它使用更好的秒表,但在这个时间尺度上几乎没有用处)。我认为这是因为它只需要处理本地名称空间(STORE\u FAST指令),而不必同时处理本地和全局名称空间(STORE\u NAME指令)。本地名称空间使用寄存器,而全局名称空间将其名称和对象存储在RAM中。我可能是错的。你可以用这样的技巧使这个程序的性能提高几个百分点,但真正的罪魁祸首是基本算法。一个写得好的素数筛应该几乎立即产生高达2000000的素数(当然不到一秒钟)。看看