Python因其强大,灵活且易于使用而赢得了声誉。 这些优点使它可以在越来越多的应用程序,工作流和领域中使用。 但是,这种语言的设计(即解释性,运行时动态性)意味着,Python始终比诸如C或C ++的机器本机语言慢一个数量级。
多年来,开发人员针对Python的速度限制提出了各种解决方法。 例如,您可以使用C编写性能密集型任务,然后用Python封装它; 许多机器学习库正是这样做的。 或者,您可以使用Cython这个项目,该项目使您可以在Python代码中添加运行时类型信息,以将其编译为C。
[ 也在InfoWorld上:更好的Python项目和Poetry的依赖管理 ]
但是变通办法从来都不是理想的。 如果我们可以按原样使用现有的Python程序,并以更快的速度运行它,那不是很好吗? 这正是PyPy允许您执行的操作。
相关视频:将PyPy运行时用于Python
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。 换句话说,您需要根据要运行的Python版本下载不同版本的PyPy。 PyPy的Python 2分支已经存在了很长的时间,但是Python 3版本最近才被提速。 目前,它支持Python 3.5(生产质量)和Python 3.6(测试质量)。
除了支持所有核心Python语言之外,PyPy还可以使用Python生态系统中的绝大多数工具,例如用于打包的pip
或用于虚拟环境的virtualenv
。 大多数Python程序包,即使是带有C模块的程序包,也应按原样工作,尽管我们会在下面进行限制。
PyPy如何工作
PyPy使用其他即时编译器中的动态语言优化技术。 它会分析正在运行的Python程序,以确定在对象创建并在程序中使用它们时的类型信息,然后使用该类型信息作为加速操作的指南。 例如,如果Python函数仅适用于一种或两种不同的对象类型,则PyPy会生成用于处理这些特定情况的机器代码。
[ 也在InfoWorld上:更好的Python项目和Poetry的依赖管理 ]
PyPy的优化是在运行时自动处理的,因此您通常不需要调整其性能。 高级用户可以尝试使用PyPy的命令行选项来为特殊情况生成更快的代码,但这只是很少需要的。
PyPy也偏离了CPython处理某些内部函数的方式,但是尝试保留兼容的行为。 例如,PyPy处理垃圾收集的方式与CPython不同。 一旦超出范围,并不是所有对象都会立即被收集,因此在PyPy下运行的Python程序可能会比在CPython下运行时显示更大的内存占用。 但是您仍然可以使用通过gc
模块公开的Python的高级垃圾收集控件,例如()
, ()
和()
。
如果您需要有关PyPy在运行时的JIT行为的信息,PyPy包括一个模块pypyjit ,该模块向您的Python应用程序公开了许多JIT挂钩。 如果您的某个功能或模块在JIT上表现不佳,则pypyjit
允许您获取有关其的详细统计信息。
另一个PyPy专用模块__pypy__公开了PyPy特定的其他功能,因此对于编写利用这些功能的应用程序很有用。 由于Python的运行时动态性,有可能构建PyPy时使用这些功能的Python应用程序,而当PyPy不存在时将其忽略。
PyPy限制
PyPy看起来很神奇,但这不是魔术。 PyPy具有某些限制,这些限制会降低或消除其对某些程序的有效性。 y,PyPy不能完全替代库存的CPython运行时。
PyPy最适合纯Python应用
PyPy始终在“纯” Python应用程序(即,用Python编写的应用程序)上表现最佳。 由于PyPy模仿CPython的本机二进制接口的方式,与C库(例如NumPy)接口的Python软件包的效果不佳。
PyPy的开发人员减少了这个问题,并使PyPy与大多数依赖C扩展的Python软件包更加兼容。 例如,Numpy现在与PyPy配合得很好。 但是,如果要最大程度地与C扩展兼容,请使用CPython。
PyPy最适合长时间运行的程序
PyPy如何优化Python程序的副作用之一是,运行时间更长的程序从其优化中受益最大。 程序运行的时间越长,PyPy可以收集的运行时类型信息越多,并且可以进行更多的优化。 一劳永逸的Python脚本不会从这种事情中受益。 受益匪浅的应用程序通常具有长时间运行的循环,或者在后台(例如Web框架)连续运行。
[ 通过InfoWorld Daily新闻通讯了解软件开发,云计算,数据分析和机器学习方面的最新发展 ]
PyPy不进行提前编译
PyPy 编译 Python代码,但它不是Python代码的编译器 。 由于PyPy执行优化的方式以及Python固有的动态性,因此无法将生成的JITted代码作为独立的二进制代码发出并重新使用。 必须为每次运行编译每个程序。 如果要将Python编译为可以作为独立应用程序运行的更快的代码,请使用Cython , Numba或当前正在实验的Nuitka项目。
From: /article/3385127/