导航: 起始页 > Dive Into Python > 性能优化 | << >> | ||||
Python 研究(Dive Into Python)Python 从新手到高手 [DIP_5_4_CPUG_RELEASE] |
性能优化 (Performance tuning) 是一件多姿多彩的事情。Python 是一种解释性语言并不表示你不应该担心代码优化。但也不必 太 担心。
由于代码优化过程中存在太多的不明确因素,以至于你很难清楚该从何入手。
让我们从这里开始:你真的确信你要这样做吗? 你的代码真的那么差吗?值得花时间去优化它吗?在你的应用程序的生命周期中,与花费在等待一个远程数据库服务器,或是等待用户输入相比,运行这段代码将花费多少时间?
第二,你确信已经完成代码编写了吗? 过早的优化就像是在一块半生不熟的蛋糕上撒糖霜。你花费了几小时、几天(或更长) 时间来优化你的代码以提高性能,却发现它不能完成你希望它做的工作。那是浪费时间。
这并不是说代码优化毫无用处,但是你需要检查一下整个系统,并且确定把时间花在这上面是值得的。在优化代码上每花费一分钟,就意味着你少了增加新功能、编写文档或者陪你的孩子玩或者编写单元测试的一分钟。
哦,是的,单元测试。不必我说,在开始性能优化之前你需要一个完全的单元测试集。你需要的最后一件事情就是在乱动你的算法时引入新的问题。
谨记着这些忠告,让我们来看一些优化 Python 代码的技术。 我们要研究的代码是实施 Soundex 算法。 Soundex 是一种 20 世纪在美国人口普查中归档姓氏的方法。 它把听起来相似的姓氏归在一起,使得在即便错误拼写的情况下调查者仍能查找到。 Soundex 今天仍然因差不多的原因被应用着,当然现在用计算机数据库服务器了。 大部分的数据库服务器都有 Soundex 函数。
Soundex 算法有几个差别不大的变化版本。这是本章使用的:
- 名字的第一个字母不变
- 根据特定的对照表,将剩下的字母转换为数字:
- B、 F、 P 和 V 转换为 1。
- C、 G、 J、 K、 Q、 S、 X 和 Z 转换为 2.
- D 和 T 转换为 3.
- L 转换为 4.
- M 和 N 转换为 5.
- R 转换为 6.
- 所有其他字母转换为 9.
- 去除连续重复。
- 去除所有 9 。
- 如果结果都少于四个字符(第一个字母加上后面的三位字符),就以零补齐。
- 如果结果超过四个字符,丢弃掉四位之后的字符。
比如,我的名字 Pilgrim 被转换为 P942695。 没有连续重复,所以这一步不需要做。然后是去除 9 ,剩下 P4265。 太长了,所以你把超出的字符丢弃,剩下 P426。
另一个例子: Woo 被转换为 W99,变成 W9,变成 W,然后以补零成为 W000 。
这是 Soundex 函数的第一次尝试:
例 18.1. soundex/stage1/soundex1a.py
如果您还没有下载本书附带的例子程序, 可以 下载本程序和其他例子程序。
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())
进一步阅读
- Soundexing and Genealogy 给出了 Soundex 发展的年代表以及地域变化。
<< 小结 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
使用 timeit 模块 >> |