您当前位置:首页 > 深入 Python > 性能调优 | << >> | ||||
深入 Python从 Python 新手到专家 |
性能调优是一件充满魅力的事情。尽管 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 模块 >> |