編程不是簡單的堆砌代碼,編寫過程中也需要考慮執行效率,假如一段代碼的計算複雜度較高,數據量一大就很難在有限時間內得到合理的結果,因此需要在編寫代碼的時候,儘量考慮計算的複雜度,減少無效的循環,多采用簡單運算指令,減少邏輯判斷,減少嵌套,在此基礎上再考慮代碼的可讀性,以便於團隊合作。
最近碰上一個例子,有一個人提出了一個很小的需求:有兩個數列,有可能一個長一個短,也可能一樣長,需要將兩個數列相加,並補上長數列多出來的元素,得到第三個數列,例如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
從代碼上可以看出已經得到了很大的優化,原來十多行的代碼,現在只要6、7行就能搞定了,代碼可讀性很高,很容易理解,但這隻裏仍然存在一個問題:如果a比b短,則運行效率較高,但是如果a比b長呢,則性能會大大下降,因爲循環的次數會大大增加,輸入不同的數據,執行性能就會巨大的差別,同時中間變量也發生了變化。
因此又有了第三個方案:第一步,短的向量,自動補齊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,性能也很高,不會因爲a和b長度的變化有明顯的性能偏差,第一種方法就不說了,第二種方法和第三種方法的性能比較如下:
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
假如變換a和b,方法3的性能沒有明顯的偏離。
當然,上面這個只是最近碰到的一個例子,平時工作中還會碰到許多類似的情況,在編寫代碼的時候都需要仔細考慮,不要操之過急,編程不是簡單的堆砌代碼。這方面也可以通過閱讀《編程珠璣》《代碼整潔之道》等書籍得到進一步的提高。