python进阶--性能优化1

Python写法纠正和优化:

 

bad

good

if x == None: ...

if x is None: ...

mapping = {5 : "5", 6 : "6"}
for key, val in mapping.items(): ...
for key in mapping.keys(): ...

# Use iter* methods when possible
mapping = {5: "5", 6: "6"}
for key, val in mapping.iteritems(): ...
for key in mapping: ...

if x < 10 and x > 2: ...

if 2 < x < 10: ...

al = [1, 2, 3]
for i in xrange(len(al)-1, -1, -1):
print al[i]

al = [1, 2, 3]
for el in reversed(al):
print el

if x == 1: y = fun1(x)
else if x == 2: y = fun2(x)
else if x == 3: y = fun3(x)
else: y = None

if x == 1: y = fun1(x)
elif x == 2: y = fun2(x)
elif x == 3: y = fun3(x)
else: y = None
# But sometimes a dict is better:
funs = {1: fun1, 2: fun2, 3: fun3}
y = funs.get(x, lambda x:None)(x)

from operator import add
sl = ["ab", "cd", "ef"]
all = ""
for s in sl:
all += s
# Or:
sl = ["ab", "cd", "ef"]
all = reduce(lambda x,y: x+y, sl, "")

sl = ["ab", "cd", "ef"]
all = "".join(sl)

a = "this isn't a word, right?"
a = a.replace("'", " ")
a = a.replace(".", " ")
a = a.replace("?", " ")
a = a.replace(",", "")

# .replace can be fine. This is faster:
from string import maketrans
tab = maketrans("'.?", " ")
a = "this isn't a word, right."
afilt = a.translate(tab, ",")

class Foo(object):
def __init__(self, x, y, z):
self.x_public = x
self.y_private = y
self.z_veryprivate = z
def getx(self):
return self.x_public
print Foo(1, 2, 3).getx()

# Generally getters and setters are not used.
# Instance names starting with _ are meant as
# 'to not mess with' by convention.
# Instance names starting with __ are private
# and receive name mangling.
class Foo(object):
def __init__(self, x, y, z):
self.x_public = x
self._y_private = y
self.__z_veryprivate = z
print Foo(1, 2, 3).x_public

a = "this isn't a word, right?"
a = a.replace("'", " ")
a = a.replace(".", " ")
a = a.replace("?", " ")
a = a.replace(",", "")

# .replace can be fine. This is faster:
from string import maketrans
tab = maketrans("'.?", " ")
a = "this isn't a word, right."
afilt = a.translate(tab, ",")

def mul(x, y): return x*y
l = [2, 3]
print apply(mul, l)

def mul(x, y):
return x * y
l = [2, 3]
print mul(*l)

l = [0] * 4
m = [l] * 4
m[1][1] = 5
print m

# One correct way to create a matrix:
m = [[0] * 4 for _ in xrange(4)]
m[1][1] = 5
print m  创建4*4矩阵

# sorting on the second item of the tuple
# try to remove the i index from the temporary tuples
lp = [(5J,"b"),(2J,"c"),(3+1J,"a"),(1+2J,"a")]
lp2 = [(c, i, n) for i,(n, c) in enumerate(lp)]
lp2.sort()
print [(n, c) for (c, i, n) in lp2]

from operator import itemgetter
lp = [(5J, "b"), (2J, "c"), (3+1J, "a"), (1+2J, "a")]
print sorted(lp, key=itemgetter(1))

根据元组第二项排序

vals = [5, 7 ,8]
tot = -2.0
for v in vals:
tot += v

vals = [5, 7 ,8]
tot = sum(vals, -2.0)

ll = [[1, 2, 3], [4], [5, 6]]
print sum(ll, [])

data = [[1, 2, 3], [4], [5, 6]]
result = []
for sublist in data:
result.extend(sublist)

# Or even, for max speed
from itertools import imap
data = [[1, 2, 3], [4], [5, 6]]
result = [None] * sum(imap(len, data))
pos = 0
for sublist in data:
lensl = len(sublist)
result[pos : pos+lensl] = sublist
pos += lensl

# To negate (inplace) each second
# element of alist:
result = []
for (i, v) in enumerate(alist):
# faster than i % 2
if i & 1 == 0:
result.append(v)
else:
result.append(-v)
alist[:] = result

from operator import neg
alist[1::2] = map(neg, alist[1::2])

# Or a bit slower but easier to read:
alist[1::2] = [-el for el in alist[1::2]]

偶数项变负数

freqs = {}
for c in "abracadabra":
try:
freqs[c] += 1
except:
freqs[c] = 1

# Short way:
freqs = {}
for c in "abracadabra":
freqs[c] = freqs.get(c, 0) + 1

# Often the fastest way:
freqs = {}
for c in "abracadabra":
if c in freqs:
freqs[c] += 1
else:
freqs[c] = 1

# Or better with Python 2.5+:
from collections import defaultdict
freqs = defaultdict(int)
for c in "abracadabra":
freqs[c] += 1

someitems = set([1, 2, 3])
somemap = {1:2, 3:4, 5:6}
print list(someitems)[0]
print list(somemap)[0]

someitems = set([1, 2, 3])
somemap = {1: 2, 3: 4, 5: 6}
print iter(someitems).next()
print iter(somemap).next()

from time import clock

# This works well on Windows and Linux:
from timeit import default_timer as clock
# Or often use the timeit module

 

参照:
Python best practices:
http://www.fantascienza.net/leonardo/ar/python_best_practices.html

 

python性能提升:
1. python快速的内建函数
input, int, isinstance, issubclass, iter, open, ord, pow, print, property
 
2. jion连接字符串更快,因为+会创建一个新的字符串并复制旧的内容
同理,list用extend更快
 
3. 快速交换变量,不用temp
x, y = y, x
 
4. 尽量使用局部变量
 
5. 尽量使用in
 
6. 使用延迟加载加速:将import移入函数中,需要时再导入,可以加速软件启动
可以多用from……import……
 
7. while 1:比while True:高效
 
8. list comprehension(列表解析)比for,while快
eg:evens = [i for i in range(10) if i % 2 == 0]
 
9. xrange是range的兄弟,用于需要节省内存和超大数据集合
xrange不生成整个列表
 
10. itertools模块,迭代组合
 
11. python中列表是数组,append是尾部添加,比insert首部添加要高效
deque是双链表
dict,set是哈希表
 
12. Schwartzian Transform准则
装饰——排序——去装饰
例如:使用list.sort比list.sort(cmp)高效(cmp是自己编写的函数),因此对其他结构排序,可以将其他结构装换为list
 
13. GIL全局解释器锁会序列化线程,可以考虑用multiprocessing
 
参照:
《python性能鸡汤》:
中文翻译:
http://blog.renren.com/share/101978396/12376358005
英文原文:http://blog.monitis.com/index.php/2012/02/13/python-performance-tips-part-1/
英文原文:http://blog.monitis.com/index.php/2012/03/21/python-performance-tips-part-2/

 

实用工具:
1. python -m profile 程序
性能监控
eg:
python –m profile –o stats x.py
>>> import stats
>>> p = pstats.Stats(‘stats’)   # stats为记录文件
>>> p.sort_stats(‘time’).print_stats(15)
 
详情参照:
python用profile:
http://blog.youkuaiyun.com/lanphaday/article/details/1483728

 

2. 一些有用的第三方库和工具:
NumPy:和Matlab差不多
Scipy:数值处理
GPULib
PyPy:JIT编译器,优化python代码
CPython,Boost等:python -> C
ShedSkin: python -> C++

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值