引言:优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。
优化算法
首先我们了解下算法的时间复杂度:
O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!)
我们可以知道算法时间复杂度越高的话,该程序运行所要消耗的时间就会比较大,从而降低程序运行的性能,基于此,我们需要对算法进行优化改进。
- Python中字典使用了哈希表进行存储,如果单单用于存储键值对,而不用于范围查找的话,在python中字典存储性能要比列表存储要好的多,但是如果涉及到范围查找等,那就不是很推荐用字典。
- 在集合(set) 中,set对于取交集、并集、差集等方面要比列表要优秀很多,不过需要 注意,set集合不允许有重复元素。
尽量减少循环计算
我们在写程序的时候,经常会把一些计算写在循环表达式里面,这样就导致可能一个计算式在循环里面被多次计算。 例如:
import time
su = 0
a = time.clock()
for i in '423151423':
for j in '213123':
su += int(j)+(int(i)*5/2)
print('总耗时:%s'%(time.clock()-a)) # 总耗时:8.510000000000462e-05
import time
su = 0
a = time.clock()
for i in '423151423':
t = (int(i)*5/2)
for j in '213123':
su += int(j)+t
print('总耗时:%s'%(time.clock()-a)) # 总耗时:7.08000000000028e-05
比较以上两个代码我们可以发现,第二个的耗时比第一个的耗时要快上一丢丢。
惰性计算
Lazy evaluation:延迟计算,惰性计算,指的是仅仅在真正需要执行的时候才计算表达式。
惰性计算可以避免不必要的计算,可以带来些许性能上的提升。例子:
python
代码解读
复制代码
import time su = 0 a = time.clock() flag = 0 for i in range(1000): if flag and i>0: t = 7*200-3+5 print('总耗时:%s'%(time.clock()-a)) # 总耗时:8.84999999999983e-05
python
代码解读
复制代码
import time su = 0 a = time.clock() flag = 0 for i in range(1000): if i>0 and flag: t = 7*200-3+5 print('总耗时:%s'%(time.clock()-a)) # 总耗时:0.00011240000000000555
看上图可知关于if x and y,if x or y 如果对于or条件表达式,应该将值为真可能性较高的变量写在or的前面,而and则应该推后 节省空间,使得无限循环的数据结构成为可能,
Python字符串
python 中的字符串对象是不可改变的,因此对任何字符串的操作如拼接,修改等都将产生一个新的字符串对象,而不是基于原字符串,因此这种持续的 copy 会在一定程度上影响 python 的性能。
所以在字符串处理上有以下几点建议:
-
在字符串连接的使用尽量使用 join() 而不是 +
-
多使用python对字符串处理的内置函数对字符串进行处理而不是自己进行处理,如
str.isalpha(),str.isdigit(),str.startswith(('x', 'yz')),str.endswith(('x', 'yz'))
-
在python中直接进行格式化要比字符串串联相加性能要高一些。
其他优化技巧
Python中可以直接对两个对象进行"交换赋值",也就是a,b=b,a
,而不需要借助中间变量(t=a,a=b,b=t
)来完成。
在循环的时候使用 xrange
而不是 range
;使用 xrange
可以节省大量的系统内存,因为 xrange()
在序列中每次调用只产生一个整数元素。而 range()
將直接返回完整的元素列表,用于循环时会有不必要的开销。在 python3 中 xrange
不再存在,里面 range
提供一个可以遍历任意长度的范围的 iterator
。
此外在python中可以使用局部变量就使用局部变量,因为python中访问局部变量要快于全局变量,也就是说要减少对global
的使用。说到了局部变量,在这我就想起了闭包。闭包的功能:保存函数的状态信息,使函数的局部变量信息依然可以保存下来。
此外还有:if done is not None
比语句 if done != None
更快;使用级联比较 "x < y < z"
而不是 "x < y and y < z"
;while 1
要比 while True
更快;add(a,b)
要优于 a+b
。
邀您共同加入产品经理修炼之路: