解决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 encode和decode的妙用
Sep 02 Python
python操作摄像头截图实现远程监控的例子
Mar 25 Python
python实现批量下载新浪博客的方法
Jun 15 Python
浅析Python中的for 循环
Jun 09 Python
python模块导入的细节详解
Dec 10 Python
python字符串中匹配数字的正则表达式
Jul 03 Python
提升python处理速度原理及方法实例
Dec 25 Python
浅谈Python中的异常和JSON读写数据的实现
Feb 27 Python
Python不支持 i ++ 语法的原因解析
Jul 22 Python
Django用户认证系统如何实现自定义
Nov 12 Python
python3爬虫中多线程的优势总结
Nov 24 Python
使用pytorch实现线性回归
Apr 11 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
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
thinkPHP3.2.2框架行为扩展及demo示例
2018/06/19 PHP
IE8 chrome中table隔行换色解决办法
2010/07/09 Javascript
基于jquery实现的鼠标滑过按钮改变背景图片
2011/07/15 Javascript
Extjs优化(一)删除冗余代码提高运行速度
2013/04/15 Javascript
jQuery中click事件用法实例
2014/12/26 Javascript
javascript实用方法总结
2015/02/06 Javascript
JavaScript实现找质数代码分享
2015/03/24 Javascript
JS动态改变表格边框宽度的方法
2015/03/31 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
2016/07/12 Javascript
使用Node.js给图片加水印的方法
2016/11/15 Javascript
AngularJs 利用百度地图API 定位当前位置 获取地址信息
2017/01/18 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
深入浅析Node.js单线程模型
2017/07/10 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
浅谈angular2子组件的事件传递(任意组件事件传递)
2018/09/30 Javascript
javascript异步处理与Jquery deferred对象用法总结
2019/06/04 jQuery
JavaScript计算出两个数的差值
2020/03/19 Javascript
小程序瀑布流组件实现翻页与图片懒加载
2020/05/19 Javascript
[59:07]海涛为你详解DOTA2新版本“贤哲秘契”
2014/11/22 DOTA
python给微信好友定时推送消息的示例
2019/02/20 Python
python3.4 将16进制转成字符串的实例
2019/06/12 Python
python 等差数列末项计算方式
2020/05/03 Python
Python内置函数及功能简介汇总
2020/10/13 Python
Django admin组件的使用
2020/10/24 Python
Keras保存模型并载入模型继续训练的实现
2021/02/20 Python
外企测试工程师面试题
2015/02/01 面试题
计算机专业毕业生的自我评价
2013/11/18 职场文书
中学生校园广播稿
2014/01/16 职场文书
社会实践的活动方案
2014/08/22 职场文书
小学生差生评语
2014/12/29 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
java多态注意项小结
2021/10/16 Java/Android
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
python 学习GCN图卷积神经网络
2022/05/11 Python