86

我发现当我向 Python 提出更多要求时,python 并没有 100% 使用我的机器资源,而且速度不是很快,与许多其他解释语言相比它很快,但与编译语言相比,我认为区别在于真的很了不起。

是否可以在 Python 3 中使用即时 (JIT) 编译器来加快速度?

通常,JIT 编译器是唯一可以提高解释语言性能的东西,所以我指的是这个,如果有其他解决方案可用,我很乐意接受新的答案。

4

7 回答 7

83

首先,Python 3(.x) 是一种语言,可以有任意数量的实现。好的,直到今天,除了 CPython 之外,没有任何实现实际上实现了这些版本的语言。但这会改变(PyPy 正在迎头赶上)。

回答您要问的问题:CPython、3.x 或其他版本不包含 JIT 编译器,从来没有,也可能永远不会。其他一些 Python 实现(原生的 PyPy、Jython 和 IronPython,通过为它们构建的虚拟机重新使用 JIT 编译器)确实具有 JIT 编译器。当他们添加 Python 3 支持时,他们的 JIT 编译器没有理由停止工作。

但是,当我在这里时,也让我解决一个误解:

通常,JIT 编译器是唯一可以提高解释语言性能的东西

这是不正确的。JIT 编译器最基本的形式只是消除了解释器开销,这解释了你看到的一些速度变慢,但不是大多数。一个好的JIT 编译器还会执行许多优化,这些优化通常消除了实现大量 Python 特性所需的开销(通过检测允许更有效实现的特殊情况),突出的例子是动态类型、多态性和各种内省特性。

仅仅实现一个编译器并没有帮助。您需要非常聪明的优化,其中大部分仅在非常特定的情况下和有限的时间窗口内有效。JIT 编译器在这里很容易,因为它们可以在运行时生成专门的代码(这是它们的重点),可以通过在运行时观察程序来更容易(更准确地)分析程序,并且可以在优化无效时撤消优化。与提前编译器不同,它们还可以与解释器交互,并且经常这样做是因为这是一个明智的设计决策。我想这就是为什么它们与人们心目中的解释器联系在一起的原因,尽管它们可以并且确实独立存在。

除了优化解释器的代码本身之外,还有其他方法可以使 Python 实现更快——例如,HotPy (2) 项目。但这些目前处于研究或实验阶段,尚未显示出它们在真实代码中的有效性(和成熟度)。

当然,特定程序的性能取决于程序本身,而不是语言实现。语言实现只为您可以进行一系列操作的速度设置上限。通常,您可以通过避免不必要的工作(即优化程序)来更好地提高程序的性能。无论您是通过解释器、JIT 编译器还是提前编译器运行程序,这都是正确的。如果您想要快速的东西,请不要竭尽全力获得更快的语言实现。有些应用程序由于解释和动态性的开销是不可行的,但它们并不像您想象的那么普遍(并且通常通过有选择地调用机器代码编译的代码来解决)。

于 2012-10-23T16:36:56.210 回答
16

唯一具有 JIT 的 Python 实现是PyPy。Byt - PyPy 既是 Python 2 实现又是 Python 3 实现。

于 2012-10-23T16:35:21.570 回答
10

Numba 项目应该可以在 Python 3 上运行。虽然它不是您所要求的,但您可能想尝试一下: https ://github.com/numba/numba/blob/master/docs/source/doc/userguide .rs .

它目前不支持所有 Python 语法。

于 2012-10-23T16:57:38.020 回答
7

你可以试试pypy py3 分支,它或多或少兼容 python,但是官方的 CPython 实现没有 JIT。

于 2012-10-23T16:32:31.210 回答
4

这个网站上的一些杰出的 Python 开发人员将最好地回答这个问题。

仍然我想评论:在讨论解释语言的速度时,我只想指出在这个位置托管的一个项目:计算机语言基准游戏

这是一个专门用于运行基准测试的网站。有指定的任务要做。任何人都可以用他/她的首选语言提交解决方案,然后测试比较每个解决方案的运行时间。解决方案可以进行同行评审,通常由其他人进一步改进,并根据规范检查结果。从长远来看,这是比较不同语言的最公平的基准测试系统。

从像这样的指示性摘要中可以看出,与解释语言相比,编译语言的速度相当快。然而,差异可能并不在于编译的确切类型,而是 Python(以及图中的其他比 Python 慢的)是完全动态的。可以即时修改对象。可以即时修改类型。所以一些类型检查必须推迟到运行时,而不是编译时。

因此,尽管您可以争论编译器的好处,但您必须考虑到不同语言中存在不同的功能。这些功能可能会以内在的价格出现。

最后,在谈到速度时:大多数情况下,导致问题的不是语言和语言的感知速度,而是一个糟糕的算法。我从来不用切换语言,因为一种语言太慢了:当我的代码出现速度问题时,我会修复算法。但是,如果您的代码中有耗时的、计算密集型的循环,那么重新编译这些循环通常值得的。一个突出的例子是脚本语言使用的用 C 编码的库(Perl XS 库,例如 Python 的 numpy/scipy,lapack/blas 是可用于许多脚本语言绑定的库的示例)

于 2012-10-23T16:35:22.847 回答
2

如果您指的是即时编译器中的 JIT 到字节码表示,那么它具有这样的功能(自 2.2 起)。如果您的意思是 JIT 到机器代码,那么不会。然而,编译成字节码提供了很多性能改进。如果您希望它编译为机器代码,那么 Pypy 就是您正在寻找的实现。

注意:pypy 不适用于 Python 3.x

于 2012-10-23T16:35:31.383 回答
0

如果您正在寻找代码块中的速度改进,那么您可能想看看rpythonic,它使用 pypy 编译为 C。它使用装饰器将其转换为 Python 的 JIT。

于 2013-11-19T18:52:24.067 回答