| 導航:起始頁 > Dive Into Python > 性能優化 | << >> | ||||
深入 Python :Dive Into Python 中文版Python 從新手到專家 [Dip_5.4b_CPyUG_Release] |
|||||
性能優化 (Performance tuning) 是一件多姿多彩的事情。Python 是一種解釋性語言并不表示你不應該擔心代碼優化。但也不必太 擔心。
由于代碼優化過程中存在太多的不明確因素,以至于你很難清楚該從何入手。
讓我們從這里開始:你真的確信你要這樣做嗎? 你的代碼真的那么差嗎?值得花時間去優化它嗎?在你的應用程序的生命周期中,與花費在等待一個遠程數據庫服務器,或是等待用戶輸入相比,運行這段代碼將花費多少時間?
第二,你確信已經完成代碼編寫了嗎? 過早的優化就像是在一塊半生不熟的蛋糕上撒糖霜。你花費了幾小時、幾天 (或更長) 時間來優化你的代碼以提高性能,卻發現它不能完成你希望它做的工作。那是浪費時間。
這并不是說代碼優化毫無用處,但是你需要檢查一下整個系統,并且確定把時間花在這上面是值得的。在優化代碼上每花費一分鐘,就意味著你少了增加新功能、編寫文檔或者陪你的孩子玩或者編寫單元測試的一分鐘。
哦,是的,單元測試。不必我說,在開始性能優化之前你需要一個完全的單元測試集。你最不需要的就是在亂動你的算法時引入新的問題。
謹記著這些忠告,讓我們來看一些優化 Python 代碼的技術。我們要研究的代碼是 Soundex 算法的實現。Soundex 是一種 20 世紀在美國人口普查中歸檔姓氏的方法。它把聽起來相似的姓氏歸在一起,使得在即便錯誤拼寫的情況下調查者仍能查找到。Soundex 今天仍然因差不多的原因被應用著,當然現在用計算機數據庫服務器了。大部分的數據庫服務器都有 Soundex 函數。
Soundex 算法有幾個差別不大的變化版本。這是本章使用的:
比如,我的名字 Pilgrim 被轉換為 P942695。沒有連續重復,所以這一步不需要做。然后是去除 9,剩下 P4265。太長了,所以你把超出的字符丟棄,剩下 P426。
另一個例子:Woo 被轉換為 W99,變成 W9,變成 W,然后以補零成為 W000。
這是 Soundex 函數的第一次嘗試:
如果您還沒有下載本書附帶的樣例程序, 可以 下載本程序和其他樣例程序。
import string, re charToSoundex = {"A": "9", "B": "1", "C": "2", "D": "3", "E": "9", "F": "1", "G": "2", "H": "9", "I": "9", "J": "2", "K": "2", "L": "4", "M": "5", "N": "5", "O": "9", "P": "1", "Q": "2", "R": "6", "S": "2", "T": "3", "U": "9", "V": "1", "W": "9", "X": "2", "Y": "9", "Z": "2"} def soundex(source): "convert string to Soundex equivalent" # Soundex requirements: # source string must be at least 1 character # and must consist entirely of letters allChars = string.uppercase + string.lowercase if not re.search('^[%s]+$' % allChars, source): return "0000" # Soundex algorithm: # 1. make first character uppercase source = source[0].upper() + source[1:] # 2. translate all other characters to Soundex digits digits = source[0] for s in source[1:]: s = s.upper() digits += charToSoundex[s] # 3. remove consecutive duplicates digits2 = digits[0] for d in digits[1:]: if digits2[-1] != d: digits2 += d # 4. remove all "9"s digits3 = re.sub('9', '', digits2) # 5. pad end with "0"s to 4 characters while len(digits3) < 4: digits3 += "0" # 6. return first 4 characters return digits3[:4] if __name__ == '__main__': from timeit import Timer names = ('Woo', 'Pilgrim', 'Flingjingwaller') for name in names: statement = "soundex('%s')" % name t = Timer(statement, "from __main__ import soundex") print name.ljust(15), soundex(name), min(t.repeat())
<< 小結 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
使用 timeit 模塊 >> |