导航:起始页 > 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 模块 >> |