python 性能优化

一、优化循环

循环以外能作的事不要放在循环内,好比下面的优化能够快一倍python

二、使用join合并迭代器中的字符串

join对于累加的方式,有大约5倍的提高算法

三、使用if is数据结构

使用if is Trueif == True将近快一倍app

四、使用级联比较x < y < z

x < y < z效率略高,并且可读性更好dom

五、使用**而不是pow

%timeit -n 10000 c = pow(2,20)
%timeit -n 10000 c = 2**20
10000 loops, best of 3: 284 ns per loop
10000 loops, best of 3: 16.9 ns per loop

  **就是快10倍以上!函数

六、优化包含多个判断表达式的顺序

对于and,应该把知足条件少的放在前面,对于or,把知足条件多的放在前面oop

a = range(2000)  
%timeit -n 100 [i for i in a if 10 < i < 20 or 1000 < i < 2000]
%timeit -n 100 [i for i in a if 1000 < i < 2000 or 100 < i < 20]     
%timeit -n 100 [i for i in a if i % 2 == 0 and i > 1900]
%timeit -n 100 [i for i in a if i > 1900 and i % 2 == 0]
100 loops, best of 3: 287 µs per loop
100 loops, best of 3: 214 µs per loop
100 loops, best of 3: 128 µs per loop
100 loops, best of 3: 56.1 µs per loop

七、使用dict或set查找元素

python dict和set都是使用hash表来实现,查找元素的时间复杂度是O(1)性能

八、合理使用copy与deepcopy

对于dict和list等数据结构的对象,直接赋值使用的是引用的方式。而有些状况下须要复制整个对象,这时可使用copy包里的copy和deepcopy,测试

这两个函数的不一样之处在于后者是递归复制的。效率也不同:(如下程序在ipython中运行)大数据

import copy
a = range(100000)
%timeit -n 10 copy.copy(a) # 运行10次 copy.copy(a)
%timeit -n 10 copy.deepcopy(a)
10 loops, best of 3: 1.55 ms per loop
10 loops, best of 3: 151 ms per loop


九、使用列表解析和生成器表达式

表解析要比在循环中从新构建一个新的 list 更为高效,所以咱们能够利用这一特性来提升运行的效率。

 1 from time import time  
 2  t = time()  
 3  list = ['a','b','is','python','jason','hello','hill','with','phone','test',  
 4  'dfdf','apple','pddf','ind','basic','none','baecr','var','bana','dd','wrd']  
 5  total=[]  
 6  for i in range (1000000):  
 7  for w in list:  
 8  total.append(w)  
 9  print "total run time:" 
10  print time()-t 

使用列表解析:

  1. for i in range (1000000):  
  2. a = [w for w in list] 

上述代码直接运行大概须要 17s,而改成使用列表解析后 ,运行时间缩短为 9.29s。将近提升了一半。生成器表达式则是在 2.4 中引入的新内容,语法和列表解析相似,可是在大数据量处理时,生成器表达式的优点较为明显,它并不建立一个列表,只是返回一个生成器,所以效率较高。在上述例子上中代码 a = [w for w in list] 修改成 a = (w for w in list),运行时间进一步减小,缩短约为 2.98s。

十、使用xrange代替range

在循环的时候使用 xrange 而不是 range;使用 xrange 能够节省大量的系统内存,由于 xrange() 在序列中每次调用只产生一个整数元素。而 range() 將直接返回完整的元素列表,用于循环时会有没必要要的开销。在 python3 中 xrange 再也不存在,里面 range 提供一个能够遍历任意长度的范围的 iterator。

十一、使用局部变量

使用局部变量,避免”global” 关键字。python 访问局部变量会比全局变量要快得多,因 此能够利用这一特性提高性能

 

十二、使用is not

if done is not None 比语句 if done != None 更快

1三、while 1要比while Trule更快

不少Python优化的文章,都会谈及这个。那么,到底能提升多少呢?咱们来试试看

 1 import random
 2 import time
 3 
 4 start_time = time.time()  
 5 print start_time  
 6   
 7 j = 1  
 8 while True:  
 9     j += 1  
10     end_time = time.time()  
11     if end_time - start_time >= 1 :  
12         break  
13 print j  
14 print end_time
15 
16 print "======== split =========="
17 start_time = time.time()  
18 print start_time  
19   
20 j = 1  
21 while 1:  
22     j += 1  
23     end_time = time.time()  
24     if end_time - start_time >= 1 :  
25         break  
26 print j  
27 print end_time

输出结果:

1399342863.16
2573550
1399342864.16
======== split ==========
1399342864.18
2973070
1399342865.18

一个是25万,一个是29万。大约提高了16%左右的性能。其实不是很明显。只是聊胜于无。

1四、使用内置函数更快,如add(a,b)要快于a+b

1五、若是须要交换两个变量的值使用 a,b=b,a 而不是借助中间变量 t=a;a=b;b=t;

1六、生成序列

用range()函数生成序列,与自定义序列

(1)a = range(0,6)

(2)a = [0, 1, 2, 3, 4, 5]

分别测试了一下,结果以下:

loop_num: 1029877

loop_num: 1602341

结论:仍是本身显式定义序列,效率更高。

1七、生成序列副本

 生成一个序列的副本:用copy,与用切片特性

a = [0, 1, 2, 3, 4, 5]

(1)b = copy.copy(a)

(2)b = a[:]

分别测试了一下,结果以下:

loop_num: 677838

loop_num: 1530012

结论:变通的切片应用做为拷贝,比浅拷贝函数效率更高。注意,深拷贝效率很低!

 

1八、慎用python内置函数

python内置函数,只是为了应对通用状况。在不少状况下,内置函数的性能,远远不如本身写的,有针对性的函数。动动手,换个算法,就能把性能提升一倍以上。

 

1九、选择合适的格式化字符方式

s1, s2 = 'ax', 'bx' %timeit -n 100000 'abc%s%s' % (s1, s2) %timeit -n 100000 'abc{0}{1}'.format(s1, s2) %timeit -n 100000 'abc' + s1 + s2 100000 loops, best of 3: 183 ns per loop 100000 loops, best of 3: 169 ns per loop 100000 loops, best of 3: 103 ns per loop 

三种状况中,%的方式是最慢的,可是三者的差距并不大(都很是快)。(我的以为%的可读性最好)

20、合理使用del

用del能够将对象占用内存空间的引用计数值置零(Deletion of a name removes the binding of that name from the local or global namespace)。它并不能让对象占用的内存被回收,但一段内存的引用计数变为零,就说明它能够再次被从新使用了(因此del后,没必要要GC介入)。

若是不用del,下面这段代码就可能MemoryError

1 import numpy as np
2 
3 matrix1 = np.zeros((60000,100000))
4 matrix2 = np.zeros((60000,100000))
5 # using matrix1
6 # using matrix2

 

利用del,能够将用完后不必占用内存的对象删掉,下面的代码对内存耗费就没上面的大。

1 import numpy as np
2 
3 matrix1 = np.zeros((60000,100000))
4 # using matrix1
5 del matrix1
6 
7 matrix2 = np.zeros((60000,100000))
8 # using matrix2
9 del matrix2
相关文章
相关标签/搜索