解决python运行效率不高的问题


Posted in Python onJuly 20, 2020

当我们提到一门编程语言的效率时:通常有两层意思,第一是开发效率,这是对程序员而言,完成编码所需要的时间;另一个是运行效率,这是对计算机而言,完成计算任务所需要的时间。编码效率和运行效率往往是鱼与熊掌的关系,是很难同时兼顾的。不同的语言会有不同的侧重,python语言毫无疑问更在乎编码效率,life is short,we use python。

虽然使用python的编程人员都应该接受其运行效率低的事实,但python在越多越来的领域都有广泛应用,比如科学计算 、web服务器等。程序员当然也希望python能够运算得更快,希望python可以更强大。

首先,python相比其他语言具体有多慢,这个不同场景和测试用例,结果肯定是不一样的。这个网址给出了不同语言在各种case下的性能对比,这一页是python3和C++的对比,下面是两个case:

解决python运行效率不高的问题

从上图可以看出,不同的case,python比C++慢了几倍到几十倍。

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中一切都是对象,每个对象都需要维护引用计数,增加了额外的工作。

第四:python GIL,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%。感兴趣的读者可以去细读。

内容扩展

关于python运行效率的分析:

如果每次你创建一个应用程序都是用相同的编码方法,几乎肯定会导致一些你的应用程序比它能够达到的运行效率慢的情况。作为分析过程的一部分,你可以尝试一些实验。例如,在一个字典中管理一些元素,你可以采用安全的方法确定元素是否已经存在并更新,或者你可以直接添加元素,然后作为异常处理该元素不存在情况。考虑第一个编码的例子:

n = 16
myDict = {}
for i in range(0, n):
 char = 'abcd'[i%4]
 if char not in myDict:
  myDict[char] = 0
  myDict[char] += 1
  print(myDict)

这段代码通常会在myDict开始为空时运行得更快。然而,当mydict通常被数据填充(或者至少大部分被充填)时,另一种方法效果更好。

n = 16
myDict = {}
for i in range(0, n):
 char = 'abcd'[i%4]
 try:
  myDict[char] += 1
 except KeyError:
  myDict[char] = 1
 print(myDict)

两种情况下具有相同的输出:{‘d': 4, ‘c': 4, ‘b': 4, ‘a': 4}。唯一的不同是这个输出是如何得到的。跳出固定的思维模式,创造新的编码技巧,能够帮助你利用你的应用程序获得更快的结果。

Python 相关文章推荐
用python找出那些被“标记”的照片
Apr 20 Python
Python学习之用pygal画世界地图实例
Dec 07 Python
浅谈django model postgres的json字段编码问题
Jan 05 Python
详解如何在Apache中运行Python WSGI应用
Jan 02 Python
python xpath获取页面注释的方法
Jan 14 Python
python中update的基本使用方法详解
Jul 17 Python
Django shell调试models输出的SQL语句方法
Aug 29 Python
python tkiner实现 一个小小的图片翻页功能的示例代码
Jun 24 Python
Python实现一个优先级队列的方法
Jul 31 Python
Python Flask异步发送邮件实现方法解析
Aug 01 Python
python 发送邮件的四种方法汇总
Dec 02 Python
pandas 数据类型转换的实现
Dec 29 Python
Python生成器generator原理及用法解析
Jul 20 #Python
Win10环境中如何实现python2和python3并存
Jul 20 #Python
python和go语言的区别是什么
Jul 20 #Python
Python基础教程(一)——Windows搭建开发Python开发环境
Jul 20 #Python
Python字典fromkeys()方法使用代码实例
Jul 20 #Python
Python爬虫设置ip代理过程解析
Jul 20 #Python
Python如何使用27行代码绘制星星图
Jul 20 #Python
You might like
php基础知识:类与对象(2) 自动加载对象
2006/12/13 PHP
PHP图片处理之图片旋转和图片翻转实例
2014/11/19 PHP
PHP实现的增强性mhash函数
2015/05/27 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
2018/06/20 PHP
js 实现无干扰阴影效果 简单好用(附文件下载)
2009/12/27 Javascript
JQuery魔力之$("tagName")与selector
2012/03/05 Javascript
基于JQuery的一句话搞定手风琴菜单
2012/09/14 Javascript
浅谈jQuery的offset()方法及示例分享
2015/07/17 Javascript
jquery日历插件datepicker用法分析
2016/01/22 Javascript
详解JS去重及字符串奇数位小写转大写
2016/12/29 Javascript
五步轻松实现JavaScript HTML时钟效果
2020/03/25 Javascript
fetch 如何实现请求数据
2018/12/20 Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
2020/07/28 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
Python如何获取系统iops示例代码
2016/09/06 Python
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
Python实现图片转字符画的示例代码
2017/08/21 Python
python实现简单五子棋游戏
2019/06/18 Python
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
2019/08/01 Python
python集合的创建、添加及删除操作示例
2019/10/08 Python
Python:二维列表下标互换方式(矩阵转置)
2019/12/02 Python
如何在sublime编辑器中安装python
2020/05/20 Python
Python调用C/C++的方法解析
2020/08/05 Python
英国在线定制百叶窗网站:Swift Direct Blinds
2020/02/25 全球购物
Yahoo-PHP面试题4
2012/05/05 面试题
Android面试题附答案
2014/12/08 面试题
医学生临床实习自我评价
2014/03/07 职场文书
体育系毕业生求职自荐信
2014/04/16 职场文书
考博专家推荐信
2014/05/10 职场文书
会计试用期自我评价
2014/09/19 职场文书
写给老师的保证书
2015/05/09 职场文书
先进党支部事迹材料2016
2016/02/26 职场文书
互联网创业商业模式以及赚钱法则有哪些?
2019/10/12 职场文书
Python torch.flatten()函数案例详解
2021/08/30 Python
React Fragment介绍与使用详解
2021/11/11 Javascript