21

对于 Python,它可以创建一个预编译版本 file.pyc 以便程序可以运行而无需再次解释。Ruby、PHP 和 Perl 可以在命令行上做同样的事情吗?

4

11 回答 11

31

Ruby 没有可移植的字节码规范,因此也没有加载预编译字节码档案的标准方法。然而,几乎所有的 Ruby 实现都使用某种字节码或 intcode 格式,其中一些可以转储和重新加载字节码档案。

YARV总是在执行代码之前编译为字节码,但这通常只在内存中完成。有一些方法可以将字节码转储到磁盘。但是,目前无法将其读回这将在未来发生变化:YARV 字节码验证器的工作正在进行中,一旦完成,字节码可以安全地加载到 VM 中,而不必担心损坏。此外,JRuby 开发人员表示,一旦 YARV 字节码格式和验证器稳定,他们愿意在 JRuby 中实现 YARV VM 模拟器,以便您可以将 YARV 字节码加载到 JRuby 中。(请注意,此版本已过时。)

Rubinius也总是编译成字节码,它有一种编译文件的格式.rbc文件,类似于 JVM.class文件),还有一种字节码存档格式(.rba文件,类似于 JVM.jar文件)。如果将应用程序部署为 YARV 字节码变得流行,Rubinius 有可能实现 YARV 模拟器。此外,JRuby 开发人员表示,如果 Rubinius 字节码成为部署 Ruby 应用程序的流行方式,他们愿意在 JRuby 中实现 Rubinius 字节码模拟器。(请注意,此版本已过时。)

XRuby是一个纯编译器,它将 Ruby 源代码直接编译为 JVM 字节码(.class文件)。.class您可以像部署任何其他 Java 应用程序一样部署这些文件。

JRuby最初是一个解释器,但它同时有一个 JIT 编译器和一个AOT 编译器jrubyc),可以将 Ruby 源代码编译为 JVM 字节码(.class文件)。此外,正在努力创建一个的编译器,该编译器可以将 Ruby 代码编译(类型注释)为实际上看起来像 Java 类的 JVM 字节码,并且可以无障碍地从 Java 代码中使用。

Ruby.NET是一个纯编译器,可将 Ruby 源代码编译为 CIL 字节码(PE.dll.exe文件)。您可以像部署任何其他 CLI 应用程序一样部署它们。

IronRuby也编译为 CIL 字节码,但通常在内存中进行。但是,您可以将命令行开关传递给它,因此它将.dll.exe文件转储到磁盘。一旦你有了这些,它们就可以正常部署了。

BlueRuby自动将 Ruby 源代码预解析为 BRIL(BlueRuby 中间语言),它基本上是一个序列化的分析树。(有关详细信息,请参阅Blue Ruby - SAP ABAP 中的 Ruby VM (PDF)。)

认为(但我绝对不确定)有一种方法可以让Cardinal转储Parrot字节码档案。(实际上,Cardinal 只编译为 PAST,然后 Parrot 接管,因此转储和加载字节码档案将是 Parrot 的工作。)

于 2009-05-19T21:40:57.513 回答
13

Perl 5 可以将字节码转储到磁盘,但它有问题且令人讨厌。 Perl 6有一种非常简洁的方法来创建Parrot可以运行的字节码可执行文件。

Perl 的即时编译足够快,在大多数情况下这无关紧要。一个重要的地方是在 CGI 环境中,这就是mod_perl的用途。

于 2009-05-19T18:03:28.117 回答
11

对于歇斯底里的葡萄干,Perl 5在搜索模块时.pmc会先于文件查找文件。.pm这些文件可能包含字节码,尽管 Perl 默认不写出字节码(与 Python 不同)。

Module::Compile(或:这个 PMC 是什么东西?)更深入地介绍了这个晦涩的功能。它们不经常使用,但是...

编写Module::Compile的聪明人利用这一点,将 Perl 代码预编译成……好吧,它仍然是 Perl,但它是经过预处理的。

除了其他好处之外,这加快了加载时间,并且在使用源过滤器(Perl 代码在被解释器加载之前修改 Perl 源代码)时使调试更容易。

于 2009-05-19T19:01:31.453 回答
6

不适用于 PHP,尽管大多数 PHP 设置都包含一个字节码缓存,它将缓存已编译的字节码,以便下次脚本运行时运行已编译的版本。这大大加快了执行速度。

我不知道通过命令行实际获取字节码。

于 2009-05-19T18:00:43.893 回答
5

对于 Perl,您可以尝试使用B::Bytecodeperlcc。然而,这两者都是高度实验性的。Perl 6 即将推出(理论上)并将在 Parrot 上使用不同的字节码,因此所有这一切都将在当时没有实际意义。

于 2009-05-19T18:03:40.223 回答
3

这是命令行的一些示例魔术词

perl -MO=Bytecode,-H,-o"Module.pm"c "Module.pm"
于 2009-05-20T08:17:04.603 回答
2

根据Programming Perl的第三版,可以通过一些实验性的方式来近似这一点。

于 2009-05-19T18:04:58.473 回答
1

如果您在 PHP 脚本上使用Zend Guard,它实质上会将脚本预编译为字节码,如果加载了 Zend Optimizer 扩展,则可由 PHP 引擎运行。

所以,是的,Zend Guard/Optimizer 允许使用预编译的 PHP 脚本。

于 2009-05-19T18:27:13.977 回答
1

对于 PHP,Phalanger 项目编译为 .Net 程序集。我不确定这是否是你要找的。

于 2009-05-19T18:42:44.293 回答
1

有没有人考虑过使用 LLVM 的字节码,而不是另一个自定义字节码?

于 2009-06-04T08:02:15.023 回答
0

Ruby 1.8 实际上根本不使用字节码(甚至在内部),因此没有预编译步骤。

于 2009-05-19T18:05:21.500 回答