一个让Python代码运行更快的最佳方式是什么

python因其强大、灵活且易于使用等特性,而赢得了声誉。这些优点使其在各种各样的应用程序、工作流程和领域中得到了广泛应用。但是就语言的设计,也就是它天然的解释能力还有它的运行时的动态性而言,python总是比c或c ++这样的机器本地语言慢一个数量级。
多年来,开发人员已经为python的速度限制提出了各种变通方法。例如你可以在c中编写性能密集型任务并使用python封装它,许多机器学习库正是这样做的。或者你可以使用cython,这个项目可以将python种加上运行时类型信息以便编译为c,通过这种方式来允许你使用python代码。
但变通办法从来都不是理想的。如果我们能够按原样使用现有的python程序并以更快的速度运行它,那不是很好吗?这正是pypy允许你做的事情。
pypy与cpython
pypy是python解释器cpython的直接替代品。cpython将python编译为中间字节码然后由虚拟机解释,而pypy使用实时(jit)编译将python代码转换为本地机器的汇编语言。
根据正在执行的任务,性能提升可能会非常显着。平均而言,pypy将python加速了大约7.6倍,一些任务加速了50倍或更多。cpython解释器根本不会执行与pypy一样的优化方式,并且可能永远不会,因为这不是它的设计目标之一。
最好的部分是开发人员需要很少甚至不需要努力来解锁pypy提供的收益。只需将cpython替换为pypy,并且大部分都已完成。下面讨论了一些例外,但是pypy的目标是运行现有的,并且未经修改的python代码并为其提供自动化的速度提升。
pypy目前通过项目的不同版本支持python 2和python 3。换句话说,你需要下载不同版本的pypy,具体取决于你运行的python版本。 pypy的python 2分支已经存在了很长时间,但到目前为止,python 3版本的速度已经提高了很多。pypy目前支持python 3.5(发布版本)和python 3.6(beta版本)。
除了支持所有核心python语言外,pypy还可以与python生态系统中的绝大多数工具配合使用,例如用于打包的pip或用于虚拟环境的virtualenv。大多数python软件包,即使是那些带有c模块的软件包,都会按照原样运行。当然,也存在一些限制,我们将在下面介绍一些限制。
pypy如何工作
pypy使用其他即时编译器中的动态语言优化技术。它分析运行的python程序,以确定在程序中创建和使用对象时的类型信息,然后使用该类型信息作为指导来加快速度。例如,如果python函数仅使用一种或两种不同的对象类型,pypy会生成机器代码来处理这些特定情况。
pypy的优化是在运行时自动处理,因此你通常不需要调整其性能。高级用户可能会尝试使用pypy的命令行选项来为特殊情况生成更快的代码,但这种情况通常很少需要。
pypy也脱离了cpython处理一些内部函数的方式,但它同时试图保留兼容的行为。例如pypy处理垃圾回收的方式与cpython不同。并非所有对象一旦超出范围就立即回收,所以在pypy下运行的python程序可能比在cpython下运行时显示占用更大的内存。但你仍然可以使用通过gc模块公开的python高级垃圾回收控件,例如gc.enable(),gc.disable()和gc.collect()等等。
如果你想在运行时获得有关pypy的jit(实时)行为的信息,pypy包含一个模块pypyjit,它向你的python应用程序公开了许多jit关联信息。如果你的某个功能或模块在jit上表现不佳,那么pypyjit可以让你获得有关它的详细统计信息。
另一个特定于pypy的模块,__pypy__暴露了pypy特有的其他功能,因此对于编写利用这些功能的应用程序非常有用。由于python的运行的动态性,有可能构建在pypy存在时使用这些功能的python应用程序,而在不存在时忽略它们。
pypy的限制
可能看pypy起来像魔法一样神奇,但其实它并不神奇。 pypy同样具有某些限制,可以削弱或消除某些程序的有效性。唉,pypy不是cpython运行时的完全的通用替代品。
pypy最适合纯python的应用程序
pypy在“纯”python应用程序中表现最佳,换句话说也就是用python编写的没有夹杂其他语言的应用程序中表现最佳。由于pypy模仿cpython的本机二进制接口的方式,与c库(如numpy)接口的python包也没有那么出类拔萃了。
pypy的开发人员已经解决了这个问题,并使pypy与大多数依赖于c扩展的python包更加兼容。例如numpy现在与pypy兼容的非常好。但是,如果你希望与c的扩展最大程度地兼容,请使用cpython。
pypy适用于运行时间较长的程序
pypy优化python程序的一个副作用是,运行时间较长的程序通过pypy的优化获益最多。程序运行的时间越长,pypy可以收集的运行时类型信息就越多,它可以进行的优化就越多。一劳永逸的python脚本不会从这种事情中受益。例如受益的python应用程序通常具有长时间循环运行的行为,或者在web框架的后台中连续运行。
pypy没有预编译
pypy编译python代码,但它不是python代码的编译器。由于pypy执行其优化的方式和python的固有动态特点,因此无法将生成的jitted代码作为独立二进制文件发出并重新使用它。每次运行都必须编译每个程序。如果你想将python编译成可以作为独立应用程序运行的更快的代码,那么还是请使用cython、numba或当前实验性的nuitka项目。

2022送女生什么蓝牙耳机比较好?高颜值蓝牙耳机推荐
台积电:全球晶圆代工王者
直下式(或矩阵式)LED背光架构的开发兴起
三星发布采用8nm工艺的Exynos9820芯片
62篇论文入选十年来最难CVPR,商汤研究再创佳绩
一个让Python代码运行更快的最佳方式是什么
英特尔第十代酷睿曝光,i3性能上能超i7
如何为Subwoofer制作低通滤波器
音色纯美的纯直流Hi-Fi大功率纯甲类功放
打破市场格局,擦窗机器人正在打造中国“智造”新名片
苹果关闭iOS 14.2/14.2.1验证
电力系统中性点接地方式分类
管式土壤剖面水分速测仪在种植用应用
恩智浦与吉利汽车开展合作,定义下一代毫米波雷达
基于ST环境光传感器VD6283TX 针对LED投影机光源调变方案
基于锂离子电池的 MP3代替 A/D 转换器的低成本方案
在海尔的坚持下 直驱洗衣机受到越来越多的用户欢迎
电磁超声兰姆波的无损探伤测试
一种突破带宽和尺寸限制的高性能准消色差超透镜
什么是超级本?