提高python代码运行效率的一些建议


Posted in Python onSeptember 29, 2020

1. 优化代码和算法

一定要先好好看看你的代码和算法。许多速度问题可以通过实现更好的算法或添加缓存来解决。本文所述都是关于这一主题的,但要遵循的一些一般指导方针是:

  • 测量,不要猜测。 测量代码中哪些部分运行时间最长,先把重点放在那些部分上。
  • 实现缓存。 如果你从磁盘、网络和数据库执行多次重复的查找,这可能是一个很大的优化之处。
  • 重用对象,而不是在每次迭代中创建一个新对象。Python 必须清理你创建的每个对象才能释放内存,这就是所谓的“垃圾回收”。许多未使用对象的垃圾回收会大大降低软件速度。
  • 尽可能减少代码中的迭代次数,特别是减少迭代中的操作次数。
  • 避免(深度)递归。 对于 Python 解释器来说,它需要大量的内存和维护(Housekeeping)。改用生成器和迭代之类的工具。
  • 减少内存使用。 一般来说,尽量减少内存的使用。例如,对一个巨大的文件进行逐行解析,而不是先将其加载到内存中。
  • 不要这样做。 听起来很傻是吧?但是你真的需要执行这个操作吗?不能晚点儿再执行吗?或者可以只执行一次,并且它的结果可以存储起来,而不是一遍又一遍地反复计算?

2. 使用 PyPy

你可能正在使用 Python 的参考实现 CPython。之所以称为 CPython,是因为它是用 C 语言编写的。如果你确定你的代码是 CPU 密集型(CPU bound)(如果你不知道这一术语,请参见本文“使用线程”一节)的话,那么你应该研究一下 PyPy,它是 CPython 的替代方案。这可能是一种快速解决方案,无需更改任何一行代码。

PyPy 声称,它的平均速度比 CPython 要快 4.4 倍。它是通过使用一种称为 Just-in-time(JIT,即时编译)技术来实现的。Java 和 .NET 框架就是 JIT 编译的其他著名的例子。相比之下,CPython 使用解释来执行代码。虽然这一做法提供了很大的灵活性,但速度也变得慢了下来。

使用 JIT,你的代码是在运行程序时即时编译的。它结合了 Ahead-of-time(AOT,提前编译)技术的速度优势(由 C 和 C++ 等语言使用)和解释的灵活性。另一个优点是 JIT 编译器可以在运行时不断优化代码。代码运行的时间越长,它就会变得越优化。

PyPy 在过去几年中取得了长足的进步,通常情况下,它可以作为 Python 2 和 Python 3 的简易替换方案。使用 Pipenv 这样的工具,它也可以完美地工作,试试看吧!

3. 使用线程

大部分软件都是 IO 密集型,而不是 CPU 密集型。如果你对这些术语还不熟悉的话,请看看下面的解释:

  • IO 密集型(I/O bound):软件主要是等待输入 / 输出操作完成才能工作。在从网络或缓慢的存储中获取数据时,通常会出现这种情况。
  • CPU 密集型(CPU bound):软件占用了大量的 CPU 资源。它使用了 CPU 所有的能力来产生所需的结果。

在等待来自网络或磁盘的应答时,你可以使用多个线程使其他部分保持运行状态。

一个线程是一个独立的执行序列。默认情况下,Python 程序有一个主线程。但你可以创建更多的主线程,并让 Python 在它们之间切换。这种切换发生得如此之快,以至于它们看上去就好像是在同时并排运行一样。

提高python代码运行效率的一些建议

但与其他编程语言不同的是,Python 并不是同时运行的,而是轮流运行。这是因为 Python 中有一种全局解释器锁( Global Interpreter Lock,GIL)机制。这一点,以及 threading 库在 我撰写的关于 Python 并发性的文章 有详细的解释。

我们得到的结论是,线程对于 IO 密集型的软件有很大的影响,但对 CPU 密集型的软件毫无用处。

这是为什么呢?很简单。当一个线程在等待来自网络的答复时,其他线程可以继续运行。如果你要执行大量的网络请求,线程可以带来巨大的差异。如果你的线程正在进行繁重的计算,那么它们只是等待轮到它们继续计算,线程化只会带来更多的开销。

4. 使用 Asyncio

Asyncio 是 Python 中一个相对较新的核心库。它解决了与线程相同的问题:它加快了 IO 密集型软件的速度,但这是以不同的方式实现的。我将立即坦承我并非 Python 的 asyncio 拥趸。它相当复杂,特别是对于初学者来说。我遇到的另一个问题是, asyncio 库在过去几年中有了很大的发展。网上的教程和示例代码常常已经过时。不过,这并不意味着它就毫无用处。

5 同时使用多个处理器

如果你的软件是 CPU 密集型的,你通常可以用一种可以同时使用更多处理器的方式重写你的代码。通过这种方式,你就可以线性地调整执行速度。

这就是所谓的并行性,但并不是所有的算法都可以并行运行。例如,简单的将递归算法进行并行化是不可能的。但是几乎总有一种替代算法可以很好地并行工作。

使用更多处理处理器有两种方式:

  1. 在同一台机器内使用多个处理器和 / 或内核。在 Python 中,这可以通过 multiprocessing 库来完成。
  2. 使用计算机网络来使用多个处理器,分布在多台计算机上。我们称之为分布式计算。

这篇 关于 Python 并发性的文章 侧重于介绍如何在一台机器的范围内扩展 Python 软件的方法。它还介绍了 multiprocessing 库。如果你认为这是你需要的资料,一定要去看看。

与 threading 库不同, multiprocessing 库绕过了 Python 的全局解释器锁。它实际上是通过派生多个 Python 实例来实现这一点的。因此,现在你可以让多个 Python 进程同时运行你的代码,而不是在单个 Python 进程中轮流运行线程。

提高python代码运行效率的一些建议

multiprocessing 库和 threading 库非常相似。可能出现的问题是:为什么还要考虑线程呢?答案是可以猜得到的。线程是“轻量”的:它需要更少的内存,因为它只需要一个正在运行的 Python 解释器。产生新进程也还有其开销。因此,如果你的代码是 IO 密集型的,线程可能就足够好了。

一旦你实现了软件的并行工作,那么在使用 Hadoop 之类的分布式计算方面就前进了一小步。通过利用云计算平台,你可以相对轻松地进行扩展规模。例如,你可以在云端中处理大型数据集,并在本地使用结果。使用混合操作的方式,你可以节省一些资金,因为云端中的算力非常昂贵。

总结

总结起来就是:

  • 首先考虑优化你的算法和代码。
  • 如果原始速度可以解决你的问题,请考虑使用 PyPy。
  • 对 IO 密集型软件使用 threading 库和 asyncio 。
  • 使用 multiprocessing 库解决 CPU 密集型问题。
  • 如果所有这些措施还不够的话,可以利用 Hadoop 等云计算平台进行扩展规模。

以上就是提高python代码运行效率的一些建议的详细内容,更多关于提高python代码运行效率的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python第三方库xlrd/xlwt的安装与读写Excel表格
Jan 21 Python
浅谈Matplotlib简介和pyplot的简单使用——文本标注和箭头
Jan 09 Python
Python线程创建和终止实例代码
Jan 20 Python
Python八皇后问题解答过程详解
Jul 29 Python
python 字符串常用函数详解
Sep 11 Python
tensorflow中tf.slice和tf.gather切片函数的使用
Jan 19 Python
深入浅析python的第三方库pandas
Feb 13 Python
关于python中的xpath解析定位
Mar 06 Python
PyTorch在Windows环境搭建的方法步骤
May 12 Python
python爬虫构建代理ip池抓取数据库的示例代码
Sep 22 Python
Python3中FuzzyWuzzy库实例用法
Nov 18 Python
python如何用matplotlib创建三维图表
Jan 26 Python
Python爬取微信小程序Charles实现过程图解
Sep 29 #Python
Python Charles抓包配置实现流程图解
Sep 29 #Python
python和node.js生成当前时间戳的示例
Sep 29 #Python
python实现图书馆抢座(自动预约)功能的示例代码
Sep 29 #Python
Python 下载Bing壁纸的示例
Sep 29 #Python
pycharm 2020 1.1的安装流程
Sep 29 #Python
利用django创建一个简易的博客网站的示例
Sep 29 #Python
You might like
php 远程关机操作的代码
2008/12/05 PHP
php 获得汉字拼音首字母的函数
2009/08/01 PHP
解析PHP自带的进位制之间的转换函数
2013/06/08 PHP
php实现执行某一操作时弹出确认、取消对话框
2013/12/30 PHP
深入解析WordPress中加载模板的get_template_part函数
2016/01/11 PHP
详解php中serialize()和unserialize()函数
2017/07/08 PHP
Laravel程序架构设计思路之使用动作类
2018/06/07 PHP
Js+XML 操作
2006/09/20 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
jquery实现非叠加式的搜索框提示效果
2014/01/07 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
jQuery插件HighCharts绘制2D金字塔图效果示例【附demo源码下载】
2017/03/09 Javascript
jQuery判断邮箱格式对错实例代码讲解
2017/04/12 jQuery
Vue非父子组件通信详解
2017/06/12 Javascript
JavaScript hasOwnProperty() 函数实例详解
2017/08/04 Javascript
详解Node.js异步处理的各种写法
2019/06/09 Javascript
前端vue-cli项目中使用img图片和background背景图的几种方法
2019/11/13 Javascript
如何在wxml中直接写js代码(wxs)
2019/11/14 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
浅析python打包工具distutils、setuptools
2018/04/20 Python
解决pycharm无法调用pip安装的包问题
2018/05/18 Python
Python高级用法总结
2018/05/26 Python
谈一谈基于python的面向对象编程基础
2019/05/21 Python
浅谈pytorch torch.backends.cudnn设置作用
2020/02/20 Python
纯CSS3实现手风琴风格菜单具体步骤
2013/05/06 HTML / CSS
怎样实现H5+CSS3手指滑动切换图片的示例代码
2019/05/05 HTML / CSS
JD Sports德国官网:英国领先的运动鞋和运动服饰零售商
2018/02/26 全球购物
团工委书记自荐书范文
2013/12/17 职场文书
生产车间主管岗位职责
2013/12/28 职场文书
安全大检查反思材料
2014/01/31 职场文书
热情服务标语
2014/10/07 职场文书
2015年元旦标语大全
2014/12/09 职场文书
婚礼女方父母答谢词
2015/01/04 职场文书
与Windows10相比Windows11有哪些改进?值不值得升级?
2021/11/21 数码科技
Golang连接并操作MySQL
2022/04/14 MySQL