作家
登录

Python性能优化

作者: 来源: 2017-08-08 10:47:41 阅读 我要评论

正文

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

  1. # -*- coding: UTF-8 -*- 
  2.  
  3.   
  4.  
  5. from cProfile import Profile 
  6.  
  7. import math 
  8.  
  9. def foo(): 
     1/7    1 2 3 4 5 6 下一页 尾页

      推荐阅读

      做大数据真的能赚钱吗?

    于IT业内,大年夜数据之火热程度,似乎无出其右者。当然,在颇┞锋正爆发前夕,也应当合时泼盆冷水。谁能接触到数据国内冠以大年夜数据之名的企业数以千计,但细分其专注范畴,大年夜致可>>>详细阅读


    本文标题:Python性能优化

    地址:http://www.17bianji.com/lsqh/36589.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)