python下代碼優化的一個例子

   編程不是簡單的堆砌代碼,編寫過程中也需要考慮執行效率,假如一段代碼的計算複雜度較高,數據量一大就很難在有限時間內得到合理的結果,因此需要在編寫代碼的時候,儘量考慮計算的複雜度,減少無效的循環,多采用簡單運算指令,減少邏輯判斷,減少嵌套,在此基礎上再考慮代碼的可讀性,以便於團隊合作。

   最近碰上一個例子,有一個人提出了一個很小的需求:有兩個數列,有可能一個長一個短,也可能一樣長,需要將兩個數列相加,並補上長數列多出來的元素,得到第三個數列,例如a = [1,2,3,4,5] b=[1,2,3],最後得到數列c=[2,4,6,4,5],需求很簡單,然後一個新人給出瞭如下的代碼(用PYTHON實現):

 

a = [1,2,3,4,5]
b = [9,8,7,6,5]
 
def judge1(a,b):                
     c = []
     if len(a) > len(b):
        for i in range(len(b)):
            c.append(a[i]+b[i])
        for j in range(len(a) - len(b)):
            c.append(a[len(b)+j])
   
     if len(b) > len(a):
        for i in range(len(a)):
            c.append(a[i]+b[i])
        for j in range(len(b) - len(a)):
            c.append(b[len(a)+j])
   
     if len(a) == len(b):
        for i in range(len(b)):
            c.append(a[i]+b[i])

   

 

  看以上代碼,一堆的循環和判斷,並有許多重複代碼,可讀性極差,這是初學者常犯的錯誤。然後第二個人提出了優化方案:

 

def judge2(a,b):
    i=0
    for data in a:
        if(i>=len(b)):
           b.append(data)
        else:
            b[i]+=data;
        i+=1
   
    return b


 

    從代碼上可以看出已經得到了很大的優化,原來十多行的代碼,現在只要67行就能搞定了,代碼可讀性很高,很容易理解,但這隻裏仍然存在一個問題:如果ab短,則運行效率較高,但是如果ab長呢,則性能會大大下降,因爲循環的次數會大大增加,輸入不同的數據,執行性能就會巨大的差別,同時中間變量也發生了變化。

    因此又有了第三個方案:第一步,短的向量,自動補齊0元素,並保證兩個向量的長度一致,第二步:兩個向量直接相加,這樣就可以大大提高代碼的運行效率,如下:

 

def judge3(a, b):
    if len(a)< len(b):
        l = len(b)-len(a)
        t = a + [0 for x in range(0, l)]
        k = b
    else:
        l = len(b)-len(a)
        t = b + [0 for x in range(0, l)]
        k = a
    result = [t[i] + k[i] for i in range(0,len(t))]
    print result

 

如上代碼,代碼很容易理解,首先判斷兩個向量的長度,短的自動補齊0元素,然後兩個向量進行對位相加,最後就能得到結果,代碼很容易理解,非常pythonic,性能也很高,不會因爲ab長度的變化有明顯的性能偏差,第一種方法就不說了,第二種方法和第三種方法的性能比較如下:

 

  

                
if __name__ =='__main__':
    a = [2000 for x in range(0, 10000)]
    b = [100 for x in range(0, 100)]
   
    time1= time.time()
    for i in range(1000):
        judge2(a,b)
        judge3(b,a)
       
    time2= time.time()
    print u"方法2總用時:%d" % (time2-time1)     
  
    time1= time.time()
    for i in range(1000):
        judge2(a,b)
        judge3(b,a)
       
    time2= time.time()
    print u"方法3總用時:%d" % (time2-time1)

 

 

最後得出如下測試結果:

方法2總用時:6
方法3總用時:1

 

假如變換ab,方法3的性能沒有明顯的偏離。

 

當然,上面這個只是最近碰到的一個例子,平時工作中還會碰到許多類似的情況,在編寫代碼的時候都需要仔細考慮,不要操之過急,編程不是簡單的堆砌代碼。這方面也可以通過閱讀《編程珠璣》《代碼整潔之道》等書籍得到進一步的提高。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章