解决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的文件类型
May 30 Python
使用anaconda的pip安装第三方python包的操作步骤
Jun 11 Python
用python 实现在不确定行数情况下多行输入方法
Jan 28 Python
Python 写入训练日志文件并控制台输出解析
Aug 13 Python
python实现网站微信登录的示例代码
Sep 18 Python
OpenCV+Python--RGB转HSI的实现
Nov 27 Python
基于python-pptx库中文文档及使用详解
Feb 14 Python
python 控制台单行刷新,多行刷新实例
Feb 19 Python
详解Pycharm安装及Django安装配置指南
Sep 15 Python
Python实现Kerberos用户的增删改查操作
Dec 14 Python
Python非单向递归函数如何返回全部结果
Dec 18 Python
python - timeit 时间模块
Apr 06 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
jQuery+PHP+ajax实现微博加载更多内容列表功能
2014/06/27 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
javascript动态生成树形菜单的方法
2015/11/14 Javascript
基于JavaScript实现网页倒计时自动跳转代码
2015/12/28 Javascript
JavaScript禁止用户多次提交的两种方法
2016/07/24 Javascript
javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)
2016/09/20 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
Vue中如何实现proxy代理
2018/04/20 Javascript
JS实现可针对算术表达式求值的计算器功能示例
2018/09/04 Javascript
vue实现自定义日期组件功能的实例代码
2018/11/06 Javascript
详解JavaScript函数callee、call、apply的区别
2019/03/08 Javascript
vue实现可视化可拖放的自定义表单的示例代码
2019/03/20 Javascript
koa2 从入门到精通(小结)
2019/07/23 Javascript
ElementUI radio组件选中小改造
2019/08/12 Javascript
JS实现简易贪吃蛇游戏
2020/08/24 Javascript
解决vue项目运行npm run serve报错的问题
2020/10/26 Javascript
vue中如何自定义右键菜单详解
2020/12/08 Vue.js
python使用PythonMagick将jpg图片转换成ico图片的方法
2015/03/26 Python
Python序列操作之进阶篇
2016/12/08 Python
python中从str中提取元素到list以及将list转换为str的方法
2018/06/26 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
python实现抽奖小程序
2020/04/15 Python
django自定义非主键自增字段类型详解(auto increment field)
2020/03/30 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
Pytorch 图像变换函数集合小结
2021/02/01 Python
CSS3 毛玻璃效果
2019/08/14 HTML / CSS
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
科技开发中心办公室主任岗位责任制
2014/02/10 职场文书
数学兴趣小组活动总结
2014/07/08 职场文书
新颖的化妆品活动方案
2014/08/21 职场文书
计算机实训报告范文
2014/11/05 职场文书
小组组名及励志口号
2015/12/24 职场文书
文明和谐家庭事迹材料(2016精选版)
2016/02/29 职场文书
浅谈Redis存储数据类型及存取值方法
2021/05/08 Redis