2013-10-13 28 views
1

下面的程序(這是內部功能的素數)的運行時間爲110.726383227秒如何提高這個程序的效率?

如果我運行同一程序,而不在一個函數(總理)包裝它,它的運行時間222.006502634秒

我做通過將其封裝在一個函數中可顯着提高性能。

還有沒有可能提高這個程序的效率?

# 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" 
+0

使用'timeit'模塊測試程序的時機並不'time.clock()'。 –

+0

@hcwhsa'timeit'非常棒,但是當一次運行需要幾分鐘時,這是不切實際的。它專爲小片段而設計。使用'timeit'來進行單次運行是沒有用的(它使用了更好的秒錶,但在這個時間尺度上這沒什麼用處)。 – delnan

+0

我認爲這是因爲它只需要處理本地命名空間(STORE_FAST指令)而不是本地和全局命名空間(STORE_NAME指令)。本地名稱空間使用寄存器,而全局名稱空間將其名稱和對象存儲在RAM中。但我可能是錯的。 – Shashank

回答

1

如果你想解決它無需外部庫,也有一些明顯的改進可以使:

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秒。

如果使用外部庫是允許的,我建議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秒

0

這可能與python如何解析變量有關。粗略地說,當你輸入一個函數時,python會創建一個新的名稱空間,它本質上映射到該函數本地的所有變量。 Python然後可以使用一個名稱空間來確定程序員正在訪問的所有變量的值。變量名稱解析的順序如下:本地命名空間

  • 查找變量名

    • 查找變量名在全局命名空間
    • 在Python的內置插件查找名。

    執行查找可能很昂貴,並且Python中的一般表現技巧是use local variables因爲這個原因:在最低限度,就會避免做兩個查找,而不是一個。此外,較新的python編譯器似乎也在進行額外的優化,即使刪除了單個的lookup into the local namespace,但只是將該變量視爲立即值。

    測試這種優化是否僅僅因爲命名空間查找而發生的一種好方法可能是(禁止其他我不知道的優化)將所有的邏輯封裝在一個函數中,但是要使所有的變量「重新使用全球。如果一切都變慢了,你可能會猜測這是花費這麼多時間的命名空間查找。