阅读 Zen of Python,在Python理会器中输入 import this. 一个犀利的Python新手大概会留意到"理会"一词, 认为Python不外是另一门剧本语言. "它必定很慢!"
毫无疑问Python措施没有编译型语言高效快速. 甚至Python拥护者们会汇报你Python不适合这些规模. 然而,YouTube已用Python处事于每小时4千万视频的请求. 你所要做的就是编写高效的代码和需要时利用外部实现(C/C++)代码. 这里有一些发起,可以辅佐你成为一个更好的Python开拓者:
1. 利用内建函数: 你可以用Python写出高效的代码,但很难击败内建函数. 经查证. 他们很是快速.2.利用join()毗连字符串. 你可以利用 "+" 来毗连字符串. 但由于string在Python中是不行变的,每一个"+"操纵城市建设一个新的字符串并复制旧内容. 常见用法是利用Python的数组模块单个的修改字符;当完成的时候,利用 join() 函数建设最终字符串.
>>> #This is good to glue a large number of strings
>>> for chunk in input():
>>> my_string.join(chunk)
3. 利用Python多重赋值,互换变量
这在Python中即优雅又快速:
>>> x, y = y, x
这样很慢:
>>> temp = x
>>> x = y
>>> y = temp
4. 只管利用局部变量
Python 检索局部变量比检索全局变量快. 这意味着,制止 "global" 要害字.
5. 只管利用 "in"
利用 "in" 要害字. 简捷而快速.
>>> for key in sequence:
>>> print “found”
6. 利用延迟加载加快
將 "import" 声明移入函数中,仅在需要的时候导入. 换句话说,假如某些模块不需顿时利用,稍后导入他们. 譬喻,你不必在一开使就导入大量模块而加快措施启动. 该技能不能提高整体机能. 但它可以辅佐你更平衡的分派模块的加载时间.
7. 为无限轮回利用 "while 1"
有时候在措施中你需一个无限轮回.(譬喻一个监听套接字的实例) 尽量 "while true" 能完成同样的事, 但 "while 1" 是单步运算. 这招能提高你的Python机能.
>>> while 1:
>>> #do stuff, faster with while 1
>>> while True:
>>> # do stuff, slower with wile True
8. 利用list comprehension
从Python 2.0 开始,你可以利用 list comprehension 代替大量的 "for" 和 "while" 块. 利用List comprehension凡是更快,Python理会器能在轮回中发明它是一个可预测的模式而被优化.特别长处是,list comprehension更具可读性(函数式编程),并在大大都环境下,它可以节减一个特另外计数变量。譬喻,让我们计较1到10之间的偶数个数:
>>> # the good way to iterate a range
>>> evens = [ i for i in range(10) if i%2 == 0]
>>> [0, 2, 4, 6, 8]
>>> # the following is not so Pythonic
>>> i = 0
>>> evens = []
>>> while i < 10:
>>> if i %2 == 0: evens.append(i)
>>> i += 1
>>> [0, 2, 4, 6, 8]
9. 利用xrange()处理惩罚长序列:
这样可为你节减大量的系统内存,因为xrange()在序列中每次挪用只发生一个整数元素。而相反 range(),它將直接给你一个完整的元素列表,用于轮回时会有不须要的开销。
10. 利用 Python generator:
这也可以节减内存和提高机能。譬喻一个视频流,你可以一个一个字节块的发送,而不是整个流。譬喻,
>>> chunk = ( 1000 * i for i in xrange(1000))
>>> chunk
<generator object
>>> chunk.next()
0
>>> chunk.next()
1000
>>> chunk.next()
2000
11. 相识itertools模块:
该模块对迭代和组合长短常有效的。让我们生成一个列表[1,2,3]的所有分列组合,仅需三行Python代码:
>>> import itertools
>>> iter = itertools.permutations([1,2,3])
>>> list(iter)
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
12. 进修bisect模块保持列表排序:
这是一个免费的二分查找实现和快速插入有序序列的东西。也就是说,你可以利用:
>>> import bisect
>>> bisect.insort(list, element)
你已將一个元素插入列表中, 而你不需要再次挪用 sort() 来保持容器的排序, 因为这在长序列中这会很是昂贵.
13. 领略Python列表,实际上是一个数组:
#p#分页标题#e#
Python中的列表实现并不是以人们凡是谈论的计较机科学中的普通单链表实现的。Python中的列表是一个数组。也就是说,你可以以常量时间O(1) 检索列表的某个元素,而不需要从新开始搜索。这有什么意义呢? Python开拓人员利用列表工具insert()时, 需三思. 譬喻:>>> list.insert(0,item)
在列表的前面插入一个元素效率不高, 因为列表中的所有后续下标不得不改变. 然而,您可以利用list.append()在列表的尾端有效添加元素. 挑先deque,假如你想快速的在两插入或时。它是快速的,因为在Python中的deque用双链表实现。不再多说。
14. 利用dict 和 set 测试成员: 查抄一个元素是在dicitonary或set是否存在 这在Python中很是快的。这是因为dict和set利用哈希表来实现。查找效率可以到达O(1)。因此,假如您需要常常查抄成员,利用 set 或 dict做为你的容器.
>>> mylist = ['a', 'b', 'c'] #Slower, check membership with list:
>>> ‘c’ in mylist
>>> True
>>> myset = set(['a', 'b', 'c']) # Faster, check membership with set:
>>> ‘c’ in myset:
>>> True
15. 利用Schwartzian Transform 的 sort():
原生的list.sort()函数长短常快的。 Python会按自然顺序排序列表。有时,你需要非自然顺序的排序。譬喻,你要按照处事器位置排序的IP地点。 Python支持自界说的较量,你可以利用list.sort(CMP()),这会比list.sort()慢,因为增加了函数挪用的开销。假如机能有问 题,你可以申请Guttman-Rosler Transform,基于Schwartzian Transform. 它只对实际的要用的算法有乐趣,它的扼要事情道理是,你可以调动列表,并挪用Python内置list.sort() – > 更快,而无需利用list.sort(CMP() )->慢。
16. Python装饰器缓存功效:
“@”标记是Python的装饰语法。它不但用于追查,锁或日志。你可以装饰一个Python函数,记着挪用功效供后续利用。这种技能被称为memoization的。下面是一个例子:
>>> from functools import wraps
>>> def memo(f):
>>> cache = { }
>>> @wraps(f)
>>> def wrap(*arg):
>>> if arg not in cache: cache['arg'] = f(*arg)
>>> return cache['arg']
>>> return wrap
我们也可以对 Fibonacci 函数利用装饰器:
>>> @memo
>>> def fib(i):
>>> if i < 2: return 1
>>> return fib(i-1) + fib(i-2)
这里的要害思想是:加强函数(装饰)函数,记着每个已经计较的Fibonacci值;假如它们在缓存中,就不需要再计较了.
17. 领略Python的GIL(全局表明器锁):
GIL是须要的,因为CPython的内存打点长短线程安详的。你不能简朴地建设多个线程,并但愿Python能在多焦点的呆板上运行得更快。这是因为 GIL將会防备多个原生线程同时执行Python字节码。换句话说,GIL將序列化您的所有线程。然而,您可以利用线程打点多个派生历程加快措施,这些程 序独立的运行于你的Python代码外。
18. 像熟悉文档一样的熟悉Python源代码:
Python有些模块为了机能利用C实现。当机能至关重要而官方文档不敷时,可以自由摸索源代码。你可以找到底层的数据布局和算法。 Python的源码库就是一个很棒的处所:http://svn.python.org/view/python/trunk/Modules
结论:
#p#分页标题#e#
这些不能替代大脑思考. 打开引擎盖充实相识是开拓者的职责,使得他们不会快速拼凑出一个垃圾设计. 本文的Python发起可以辅佐你得到好的机能. 假如速度还不足快, Python將需要借助外力:阐明和运行外部代码.我们將在本文的第二部门中涉及.