解决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 中文字符串的处理实现代码
Oct 25 Python
深入探究Python中变量的拷贝和作用域问题
May 05 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
Sep 26 Python
Python双向循环链表实现方法分析
Jul 30 Python
Linux下多个Python版本安装教程
Aug 15 Python
python递归实现快速排序
Aug 18 Python
Python语法分析之字符串格式化
Jun 13 Python
使用IDLE的Python shell窗口实例详解
Nov 19 Python
Django Haystack 全文检索与关键词高亮的实现
Feb 17 Python
Python使用正则表达式实现爬虫数据抽取
Aug 17 Python
Window10上Tensorflow的安装(CPU和GPU版本)
Dec 15 Python
详解Python为什么不用设计模式
Jun 24 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之字符串变相相减的代码
2007/03/19 PHP
PHP 源代码压缩小工具
2009/12/22 PHP
如何突破PHP程序员的技术瓶颈分析
2011/07/17 PHP
PHP中error_log()函数的使用方法
2015/01/20 PHP
php pthreads多线程的安装与使用
2016/01/19 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
jQuery EasyUI中对表格进行编辑的实现代码
2010/06/10 Javascript
javascript取消文本选定的实现代码
2010/11/14 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
node.js中的fs.rmdirSync方法使用说明
2014/12/16 Javascript
JQuery自动触发事件的方法
2015/06/13 Javascript
jquery判断密码强度的验证代码
2020/04/22 Javascript
解析JavaScript模仿块级作用域
2016/12/29 Javascript
bootstrap中模态框、模态框的属性实例详解
2017/02/17 Javascript
微信小程序如何引用外部js,外部样式,公共页面模板
2019/07/23 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
vue使用video插件vue-video-player详解
2020/10/23 Javascript
ES2020让代码更优美的运算符 (?.) (??)
2021/01/04 Javascript
python查询sqlite数据表的方法
2015/05/08 Python
Django日志模块logging的配置详解
2017/02/14 Python
基于Python_脚本CGI、特点、应用、开发环境(详解)
2017/05/23 Python
Windows系统下多版本pip的共存问题详解
2017/10/10 Python
pandas中Timestamp类用法详解
2017/12/11 Python
python模拟表单提交登录图书馆
2018/04/27 Python
搭建python django虚拟环境完整步骤详解
2019/07/08 Python
Python编译成.so文件进行加密后调用的实现
2019/12/23 Python
django数据模型中null和blank的区别说明
2020/09/02 Python
英国折扣高尔夫商店:Discount Golf Store
2019/11/19 全球购物
大专毕业生自我鉴定
2013/11/21 职场文书
平安工地建设方案
2014/05/06 职场文书
公司会议策划方案
2014/05/17 职场文书
节水标语大全
2014/06/11 职场文书
员工团队活动方案
2014/08/28 职场文书
MySQL索引 高效获取数据的数据结构
2022/05/02 MySQL