python高性能编程方法一-乾颐堂

阅读 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 at 0x7f65d90dcaa0>

>>> 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列表,实际上是一个数组:

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建议可以帮助你获得好的性能. 如果速度还不够快, Python將需要借助外力:分析和运行外部代码.我们將在本文的第二部分中涉及.

www.qytang.com/
http://www.qytang.com/cn/list/29/
http://www.qytang.com/cn/list/28/358.htm
http://www.qytang.com/cn/list/41/
http://www.qytang.com/cn/list/37/
http://www.qytang.com/cn/list/46/
http://www.qytang.com/cn/page/19.htm
http://www.qytang.com/cn/list/32/
http://www.qytang.com/cn/list/28/
http://www.qytang.com/cn/list/25/
http://www.qytang.com/cn/list/28/625.htm
http://www.qytang.com/cn/list/28/612.htm
http://www.qytang.com/cn/list/28/611.htm

时间: 2024-10-06 13:30:35

python高性能编程方法一-乾颐堂的相关文章

Python服务器开发 -- 网络基础-乾颐堂

网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据. 我们在传输数据时,可以只使用(传输

python时间处理详解-乾颐堂

1.获取当前时间的两种方法: import datetime,time now = time.strftime("%Y-%m-%d %H:%M:%S") print now now = datetime.datetime.now() print now 2.获取上个月最后一天的日期(本月的第一天减去1天) last = datetime.date(datetime.date.today().year,datetime.date.today().month,1)-datetime.tim

python高性能编程方法一

python高性能编程方法一 阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为Python不过是另一门脚本... 阅读 Zen of Python,在Python解析器中输入 import this. 一个犀利的Python新手可能会注意到"解析"一词, 认为Python不过是另一门脚本语言. "它肯定很慢!" 毫无疑问Python程序没有编译型语言

乾颐堂安德华为数通HCNA真题解析版(第2部分)

HCNA真题解析视频即将上线,敬请关注本博客以及乾颐堂官网书接上文:16 Interface GigabitEthernet0/0/1 Port link‐type trunk Port trunk allow‐pass vlan 2 to 4094 根据如上所示的命令输出,下列描述中正确的是()(多选)A GigabitEthernet0/0/1 不允许 VLAN1 通过B GigabitEthernet0/0/1 允许 VLAN1 通过C 如果要把 GigabitEthernet0/0/1

乾颐堂鹏同学通过HCIE送给后来者的话

HCIE备考分享最先在考CCIE还是HCIE的时候,还是很犹豫的,CCIE至少都要到北京考试,并且我之前也考过CCNP的,感觉还是有些基础的,但是考试的成本会增加,HCIE在成都就可以考,路途等各种成本基本不用,听说面试比较难.综合考虑了一下,最终还是选择了考HCIE(想挑战一下自己).决定好以后,就开始准备考试,笔试很简单,题库刷了几遍就OK了,只要背好了,一般都是高分通过的.接下来就是备考LAB了,LAB的建议大家按照老师的方法先敲熟悉后,实现了盲敲以后(我当时都不用看拓扑就直接敲命令了),

Python猫荐书系列之五:Python高性能编程

稍微关心编程语言的使用趋势的人都知道,最近几年,国内最火的两种语言非 Python 与 Go 莫属,于是,隔三差五就会有人问:这两种语言谁更厉害/好找工作/高工资-- 对于编程语言的争论,就是猿界的生理周期,每个月都要闹上一回.到了年末,各类榜单也是特别抓人眼球,闹得更凶. 其实,它们各有对方所无法比拟的优势以及用武之地,很多争论都是没有必要的.身为一个正在努力学习 Python 的(准)中年程序员,我觉得吧,先把一门语言精进了再说.没有差劲的语言,只有差劲的程序员,等真的把语言学好了,必定是"

乾颐堂既有老腊肉也有小鲜肉,欢迎大家来学习,大学生如何学习HCIE,答案来咯

前边给大家分享了工作20余年的刘大哥的经历,下面给大家带来20出头没毕业小伙子的在乾颐堂的学习经历 9月4号开学第一天收到了一份特别的礼物,PASS HCIE 在HCIE的路上要一步一个脚印走过来,我从去年暑假之前加入乾颐堂这个大家庭,与很多在路上的HCIE一样,从对TCP/IP的一无所知,到现在MPLE.BGP.组播全都能够深入掌握,这个和乾颐堂是分不开的. 刚到乾颐堂学习的时候,直接是暑假在光大会展脱产,本来我是学生,其余的时候还要学习别的东西,所以只有暑假有充裕的时间要把握住.2个月的时间

全网唯一华为无线HCNA真题解析版题库,来自乾颐堂安德

本部分内容来自互联网.通过它,您可以同哦过华为认证HCNA-WLAN无线(H12-311)考试.后续视频讲解会上传至51CTO学院,其他学员可以通过乾颐堂官方咨询或者群645866695咨询解析版是军哥一字一字码出来的,转载请注明出处 QUESTION 1无线网络的初步应用开始于哪段时间()? A. 一次大战期间 B. 二次大战期间 C. 20世纪后期D. 2000年以后 Correct Answer: B Explanation/Reference:2战后才初步发展,战争很多时候是促进科技进步

《Python高性能编程》——列表、元组、集合、字典特性及创建过程

这里的内容仅仅是本人阅读<Python高性能编程>后总结的一些知识,用于自己更好的了解Python机制.本人现在并不从事计算密集型工作:人工智能.数据分析等.仅仅只是出于好奇而去阅读这本书.很多人因为Python不能同时使用多颗CPU(全局解释器锁GIL),而觉得它不能实现高性能.书中有很多介绍避开GIL或者Python虚拟机的方式,例如Cython,PyPy等. 首先我们要说一下时间复杂度,可以帮助我们理解CPython编译器怎么干活: 时间复杂度 在描述算法复杂度时,经常用到o(1), o