转译解读
首先提高代码的性能不能以改变代码功能为代价。
简而言之,按照原文说的:
1.首先将代码写对
2.测试代码是否正确执行
3.如果代码效率不高就分析是哪个部分造成的。
4.优化这个部分
5.从第二步开始重复这个部分
详细的解读包括:
选择一个正确的数据结构。
这个说法深有体会。Python中多变的数据结构可以造成很大的差异,使用一个set就可以事半功倍。甚至一个自己定义的数据结构,对于内存,运算速度,处理方式等都有很大的影响。
进行排序
我在项目中也遇到过,爬取的几百万的数据URL需要进行鉴别,哪些数据抓取了哪些没有,抓取的部分还有重复。使用if x in y这种格式,则需要o(m*n)的时间复杂度。而两边都对URL进行排序后,则可以使用两个指针轻松搞定。
示例中使用了operator 模块的itemgetter() 函数,进行了快速的分类,优雅而简洁。
n = 1
import operator
nlist.sort(key=operator.itemgetter(n))
字符串组合
编写大字符串的时候,不建议使用加号拼接字符串。使用join,%s(py3中使用format方法)等官方的方法效果更好。
循环的使用
如果使用for循环进行简单而大量的操作,不妨试试map()函数,或者python2.0中就已经有的list方法直接生成。或者使用迭代器进行循环的操作。
避免使用点方法
如上,需要使用list.append()方法的时候,这些方法都是需要在每次调用的时候重新确定(原文reevaluated)的,所以可以提前代替,如re.compile()方法。
upper = str.upper
newlist = []
append = newlist.append
for word in oldlist:
append(upper(word))
使用局部变量
可以将一些代码函数化,从而将变量转为局部变量,Python获取局部变量比使用全局变量要快得多。
原文最终做了一个比较实验,将38470个单词转换成大写,结果是:
Version Time (seconds)
Basic loop 3.47
Eliminate dots 2.45
Local variable & no dots 1.79
Using map function 0.54
可见使用map具有巨大的优势。
初始化字典元素
字典的当前使用新技巧包括:使用keyError来定位没有的key,使用get()方法来返回键对应的值。字典中还有collections模块中较多的:defaultdict,OrderedDict类等。
首先在头部写明 import 声明
大量的import会影响Python的性能。虽然随处可以import, 但最好在代码的头部集中写明。
数据的聚合
一次将多个数据聚合起来传递给函数比多次调用函数的开销要小得多。
减少执行语句的数量
Python中有一个定期检查线程是否该运行的函数。这个函数的大量调用会影响性能。最好我们可以设置这个值为较大的数,或者使用少的执行语句而以空间换时间。
Python不是C
移位不一定比加法快。Python是一个高级语言,调用底层不一定快。
使用xrange而不是range
在py3中不用考虑这一条。因为range已经优化了。
对代码进行优化
有时候有些函数你知道不会执行,就可以直接省略。减少不必要的操作。
使用profile
import profile
profile.run('main()')