例如,如果我用 Java 制作一个 JVM,是否有可能使我制作的实现实际上比我用来构建这个实现的原始实现更快,即使我的实现是在原始实现之上构建的,甚至可能依赖于在那个实施?
(令人困惑……)
看看PyPy。这是一个用 Python 制作的用于 Python 的 JIT 编译器。没关系,但它怎么能声称比它正在使用和依赖的 Python 的原始实现更快呢?
例如,如果我用 Java 制作一个 JVM,是否有可能使我制作的实现实际上比我用来构建这个实现的原始实现更快,即使我的实现是在原始实现之上构建的,甚至可能依赖于在那个实施?
(令人困惑……)
看看PyPy。这是一个用 Python 制作的用于 Python 的 JIT 编译器。没关系,但它怎么能声称比它正在使用和依赖的 Python 的原始实现更快呢?
您在语言和该语言的执行设备之间感到困惑。
PyPy 比 CPython 更快的原因之一是因为 PyPy 被编译成一个完全独立的本机可执行文件,并且不依赖于 CPython,也不在 CPython 中执行。
然而,如果更高级别的解释器使用更有效的执行策略,则一种语言的低效实现有可能被用同一语言编写的解释器超越,并托管在低效的解释器中。
绝对有可能。您的 JVM 实现可以将 Java 字节码编译为优化的机器码。如果您的优化器比运行 Java 编译器的 JVM 实现更复杂,那么最终结果可能会更快。
在这种情况下,您可以在自己的源代码上运行 Java 编译器,并从那时起受益于更快的编译速度。
你说 PyPy 是 Python 的 JIT 编译器(我自己并不熟悉)。如果是这种情况,那么它将 Python 程序转换为机器代码,然后运行机器代码。另一位发帖人说 PyPy 编译器作为独立的可执行文件运行,与 CPython 分开。但即使它要在 CPython 上运行,一旦你的程序被 JIT 编译为机器代码,并且编译的机器代码正在运行,编译器的性能就不再重要了。编译器的速度只对启动时间有影响。
PyPy 不是在 Python 中实现的 Python 解释器,它是在RPython中实现的 Python 解释器和编译器,它是 Python的受限静态类型子集:
RPython 是 Python 的一个受限子集,可以进行静态分析。尽管对语言进行了补充,并且有些事情可能会出人意料地起作用,但这是应考虑的限制的粗略列表。请注意,您会遇到大量特殊情况的限制。
真正的速度差异来自这样一个事实,与将整个程序解释为字节码的 CPython 不同,PyPy 对 RPython 部分使用即时 (JIT) 编译(转换为机器代码)。
我认为不可能为该语言的语言实现解释器(称为 A),然后在该语言的另一个现有解释器(称为 B)之上运行它并执行程序(称为 P),并且让 P 在上运行(A 在 B 上运行)比在 B 上运行的 P 快。
A 的每一项操作都必须与 B 的至少一个操作一起执行。因此,即使 B 非常糟糕而 A 是最佳的,A 在 B 上运行的事实意味着 B 的糟糕情况会减慢 A .
有可能在语言本身中为一种语言实现解释器 + JIT 编译器,其中 JIT 编译器在运行时生成一些其他更快的代码,并且让 P 运行(A 在 B 上运行)比 P 在 B 上运行更快。 P 的运行时中不是 JIT 编译的部分会更慢(通常慢得多),但如果 JIT 编译器成功识别出 P 的“热”部分并比 B 更快地执行它们,那么整个系统可能会整体运行得更快.
但这并不是很有趣。也可以用该语言 (C) 为该语言实现编译器,使用现有编译器 (D) 对其进行编译,并让新的编译器语言生成比原始编译器生成的代码更快的代码。我希望这不会吓到你;应该清楚的是,D 发出的代码的速度只会对 C 的执行时间产生影响,而不会对用 C 编译的其他程序的执行时间产生影响。
用他们编译的语言编写编译器已经完成了几十年(例如,GCC 是用 C 编写的),并且与我认为您要问的真正问题并不真正相关;JIT 也不是使用自身编译语言。在这两种情况下,底层执行都不是您正在考虑的语言;通常是机器码。
但是,您的问题的来源是一种误解。PyPy 的 Python 解释器实际上并未在 Python 中实现。PyPy 项目有一个用RPython编写的 Python 解释器。RPython 是 Python 的一个子集,选择它是为了可以有效地将其编译为机器代码;作为一门语言,RPython 更像是带有类型推断和缩进块而不是大括号的 Java。PyPy 项目还有一个用 Python 编写的 RPython 编译器,并且能够(大部分)自动将 JIT 编译器添加到它编译的任何解释器中。
当您实际在生产中使用 PyPy 解释器时,您使用的是从 RPython 源代码编译的机器代码解释器,就像您使用 CPython 解释器时您使用的是从 C 源代码编译的机器代码解释器一样。如果您在另一个 Python 解释器之上执行 PyPy 解释器(您可以这样做,因为有效的 RPython 代码也是有效的 Python 代码;但不是相反),那么它的运行速度比 CPython 解释器慢得多。
pypy 翻译过程在 CPython 上运行,但输出是一个 .c 文件列表(我上次检查时为 19 个文件),然后将其编译为二进制文件:pypy-c。在运行时 pypy-c 与 CPython 没有任何关系,这就是它可以更快的原因。