解决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的几个高级语法概念浅析(lambda表达式闭包装饰器)
May 28 Python
python设计模式大全
Jun 27 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
Python动刷新抢12306火车票的代码(附源码)
Jan 24 Python
pandas 实现字典转换成DataFrame的方法
Jul 04 Python
Python全局变量与局部变量区别及用法分析
Sep 03 Python
python交换两个变量的值方法
Jan 12 Python
基于PyQt4和PySide实现输入对话框效果
Feb 27 Python
对python中的os.getpid()和os.fork()函数详解
Aug 08 Python
Python内置类型性能分析过程实例
Jan 29 Python
Python接口自动化测试框架运行原理及流程
Nov 30 Python
如何在Python中创建二叉树
Mar 30 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
php5中类的学习
2008/03/28 PHP
php实现httpclient类示例
2014/04/08 PHP
html组件不可输入(只读)同时任何组件都有效
2013/04/01 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
2013/11/25 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
2014/09/04 Javascript
浅析Bootstrap缩略图组件与警示框组件
2016/04/29 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
如何实现星星评价(jquery.raty.js插件)
2016/12/21 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
Vue自定义指令使用方法详解
2017/08/21 Javascript
微信小程序用户自定义模版用法实例分析
2017/11/28 Javascript
JSON.stringify()方法讲解
2019/01/31 Javascript
浅谈JavaScript_DOM学习篇_图片切换小案例
2019/03/19 Javascript
原生js实现trigger方法示例代码
2019/05/22 Javascript
layui表格数据重载
2019/07/27 Javascript
分享Angular http interceptors 拦截器使用(推荐)
2019/11/10 Javascript
[02:37]TI8勇士令状不朽珍藏II视频展示
2018/06/23 DOTA
[52:39]完美世界DOTA2联赛PWL S3 CPG vs Forest 第一场 12.16
2020/12/17 DOTA
Python计算三维矢量幅度的方法
2015/06/15 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
Python操作Word批量生成文章的方法
2015/07/28 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
Python 函数list&read&seek详解
2019/08/28 Python
django框架两个使用模板实例
2019/12/11 Python
Yahoo-PHP面试题4
2012/05/05 面试题
大学四年的个人自我评价
2014/01/14 职场文书
护士自我鉴定怎么写
2014/02/07 职场文书
科级干部群众路线教育实践活动个人对照检查材料
2014/09/19 职场文书
村长反四风问题个人对照检查材料
2014/09/21 职场文书
学籍证明模板
2014/11/21 职场文书
商务邀请函
2015/01/30 职场文书
食堂采购员岗位职责
2015/04/03 职场文书
2015财务年度工作总结范文
2015/05/04 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书
用Python将GIF动图分解成多张静态图片
2021/06/11 Python