正文
2017.03.10 增长了对__slots__的介绍
留意:本文除非特别指明,”python“都是代表CPython,即C说话实现的标准python,且本文所评论辩论的是版本为2.7的CPython。
python为什么机能差:
当我们提到一门编程说话的效力时:平日有两层意思,第一是开辟效力,这是对法度榜样员而言,完成编码所须要的时光;另一个是运行效力,这是对计算机而言,完成计算义务所须要的时光。编码效力和运行效力往往是鱼与熊掌的关系,是很难同时兼顾的。不合的说话会有不合的侧重,python说话毫无疑问更在乎编码效力,life is short,we use python。
起首,python比拟其他说话具体有多慢,这个不归并景和测试用例,结不雅肯定是不一样的。这个网址给出了不合说话在各类case下的机能比较,这一页是python3和C++的比较,下面是两个case:

python运算效力低,具体是什么原因呢,下列列举一些
第一:python是动态说话
一个变量所指向对象的类型在运行时才肯定,编译器做不了任何猜测,也就无大年夜优化。举一个简单的例子: r = a + b。 a和b相加,但a和b的类型在运行时才知道,对于加法操作,不合的类型有不合的处理,所以每次运行的时刻都邑去断定a和b的类型,然后履行对应的操作。而在静态说话如C++中,编译的时刻就肯定了运行时的代码。
别的一个例子是属性查找,关于具体的查找次序在《python属性查找》中有具体介绍。简而言之,拜访对象的某个属性是一个异常复杂的过程,并且经由过程同一个变量拜访到的python对象还都可能不一样(拜见Lazy property的例子)。而在C说话中,拜访属性用对象的地址加上属性的偏移就可以了。
第二:python是解释履行,然则不支撑JIT(just in time compiler)。固然大年夜名鼎鼎的google曾经测验测验Unladen Swallow 这个项目,但最终也折了。
第三:python一一切都是对象,每个对象都须要保护引用计数,增长了额外的工作。
GIL是Python最为诟病的一点,因为GIL,python中的多线程并不克不及真正的并发。如不雅是在IO bound的营业场景,这个问题并不大年夜,然则在CPU BOUND的场景,这就很致命了。所以笔者在工作中应用python多线程的情况并不多,一般都是应用多过程(pre fork),或者在加上协程。即使在单线程,GIL也会带来很大年夜的机能影响,因为python每履行100个opcode(默认,可以经由过程sys.setcheckinterval()设置)就会测验测验线程的切换,具体的源代码在ceval.c::PyEval_EvalFrameEx。
第五:垃圾收受接收,这个可能是所有具有垃圾收受接收的编程说话的通病。python采取标记和分代的垃圾收受接收策略,每次垃圾收受接收的时刻都邑中断正在履行的法度榜样,造成所谓的顿卡。infoq上有一篇文┞仿,提到禁用Python的GC机制后,Instagram机能晋升了10%。感兴趣的读者可以去细读。
我们都知道 过早的优化是罪恶之源,一切优化都须要基于profile。然则,作为一个python开辟者应当要pythonic,并且pythonic的代码往往比non-pythonic的代码效力高一些,比如:
- 应用迭代器iterator,for example:
dict的iteritems 而不是items(同itervalues,iterkeys)
应用generator,特别是在轮回中可能提前break的情况
- 断定是否是同一个对象应用 is 而不是 ==
- 断定一个对象是否在一个集合中,应用set而不是list
- 应用短路求值特点,把“短路”概率过的逻辑表达式写在前面。其他的lazy ideas也是可以的
- 对于大年夜量字符串的累加,应用join操作
- 应用for else(while else)语法
- 交换两个变量的值应用: a, b = b, a
基于profile的优化
即使我们的代码已经异常pythonic了,但可能运行效力照样不克不及知足预期。我们也知道80/20定律,绝大年夜多半的时光都消费在少量的代码片段琅绫擎了,优化的关键在于找出这些瓶颈代码。方法很多:到处加log打印时光戳、或者将困惑的函数应用timeit进行零丁测试,但最有效的是应用profile对象。

python profilers
对于python法度榜样,比较出名的profile对象有三个:profile、cprofile和hotshot。个中profile是纯python说话实现的,Cprofile将profile的部分实现native化,hotshot也是C说话实现,hotshot与Cprofile的差别在于:hotshot对目标代码的运行影响较小,价值是更多的后处理时光,并且hotshot已经停止保护了。须要留意的是,profile(Cprofile hotshot)只合适单线程的python法度榜样。
对于多线程,可以应用yappi,yappi不仅支撑多线程,还可以精确到CPU时光
对于协程(greenlet),可以应用greenletprofiler,基于yappi修改,用greenlet context hook住thread context
- # -*- coding: UTF-8 -*-
- from cProfile import Profile
- import math
- def foo():
推荐阅读
于IT业内,大年夜数据之火热程度,似乎无出其右者。当然,在颇┞锋正爆发前夕,也应当合时泼盆冷水。谁能接触到数据国内冠以大年夜数据之名的企业数以千计,但细分其专注范畴,大年夜致可>>>详细阅读
本文标题:Python性能优化
地址:http://www.17bianji.com/lsqh/36589.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示