pypy 是 python 解释器的替代品,对于某些 python 程序来说会快很多倍 · 物联网平台-威尼斯人最新

thingskit · 2020年03月12日 · 最后由 回复于 2022年07月27日 · 284 次阅读

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 项目。

作者:树懒说物联

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
网站地图