【问题标题】:Can Ruby, PHP, or Perl create a pre-compiled file for the code like Python?Ruby、PHP 或 Perl 可以为 Python 等代码创建预编译文件吗?
【发布时间】:2010-10-27 10:02:36
【问题描述】:

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

【问题讨论】:

    标签: php ruby perl pre-compilation


    【解决方案1】:

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

    【讨论】:

    • Perl 6 将在圣诞节前发布,但 Larry 没有说是哪一年。也就是说,您现在可以开始使用 Rakudo(Perl 6 实现的当前领导者)了:rakudo.org
    • 傻拉里。我真的很希望 Perl 6 快点出来。我目前正在努力安装 git 的联机帮助页,但是一旦我解决了这个问题,我可能很快就会研究 Perl 6 的实现。我可能会选择 Pugs,因为它是开始学习 Haskell 的好地方。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      YARV 总是在执行代码之前编译为字节码,但这通常只在内存中完成。有一些方法可以将字节码转储到磁盘。 At the moment, there is no way to read it back in,但是。这将在未来发生变化:YARV 字节码验证器的工作正在进行中,一旦完成,字节码可以安全地加载到 VM 中,而不必担心损坏。此外,JRuby 开发人员表示他们愿意在 YARV 字节码格式和验证器稳定后实现YARV VM emulator inside JRuby,以便您可以将 YARV 字节码加载到 JRuby 中。 (注意这个版本是obsolete。)

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

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

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

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

      IronRuby 也编译为 CIL 字节码,但通常在内存中进行。但是,您可以传递commandline switches to it,因此它将.dll.exe 文件转储到磁盘。有了这些,就可以正常部署了。

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

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

      【讨论】:

      • PAST 是指 PASM,Parrot 汇编语言吗?
      • 不,AFAICS Parrot 编译为 PAST,而不是 PASM。这是有道理的,因为这就是 Parrot 打算使用的方式:PASM 和 PIR 应该由人类编写,PAST 由编译器编写。
      • 看起来 ruby​​ 的编译版本应该有很大的性能改进,但从基准测试来看,这似乎不是真的(或者没有我想象的那么重要)。这是真的吗?如果是,你知道为什么吗?谢谢!
      • mruby 是 Ruby 的可移植字节码规范吗?
      • @ShallmentMo:不,MRuby 是 Ruby 的实现,就像 Rubinius、JRuby、Opal 一样(嗯,从技术上讲,它是一种“几乎像 Ruby”的语言的实现,但它与it)、Topaz、Cardinal、YARV、IronRuby、MagLev、MacRuby、XRuby、Ruby.NET、tinyrb 等。
      【解决方案4】:

      这里有一些用于命令行的魔术词示例

      perl -MO=Bytecode,-H,-o"Module.pm"c "Module.pm"
      

      【讨论】:

        【解决方案5】:

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

        Module::Compile (or: what's this PMC thingy?) 更深入地介绍了这个晦涩的功能。它们不经常使用,但是...

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

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

        【讨论】:

        • @Lars: "歇斯底里的葡萄干" eq "历史原因"。 Perl 5 从很早的时候就支持 .pmc 文件,但它多年来一直未被使用,直到被一些 Perl 6 实现者重新发现。
        • “历史原因”。这是一个流行的双关语。
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

            • 那个字节码的东西似乎在 5.10 中被破坏/删除了。等待6
            • 和 s/mod_perl/fastcgi/恕我直言。
            【解决方案9】:

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

            【讨论】:

            • 但是当前版本可以。
            • 这根本不是真的。几乎所有 Ruby 1.8 的实现(只有一个例外)都可以编译为字节码。事实上,有几个实现只能编译,它们甚至没有解释器。
            • @Jörg:只有一个实现本身被恰当地称为“Ruby 1.8”,那就是 Matz 编写的 Ruby 解释器的 1.8 版。其他的还有 Jruby、Rubinius 等。
            • JRuby 和 Rubinius(以及 XRuby、IronRuby、Ruby.NET、MagLev、tinyrb 等)都是 Ruby 1.8 的实现。他们都使用字节码。 Ruby 1.8 中 使用字节码的唯一 实现是MRI。你怎么能声称 Ruby 1.8 不使用字节码,而除了一个之外的所有实现都确实使用字节码?在我的回答中,我列出了不少于 6 种不同的 Ruby 1.8 实现,它们不仅使用字节码,而且实际上可以做原始发帖人想要的。
            • 当然,OP 询问的是 Ruby,而不是 Ruby 1.8,所以如果您将 Ruby 1.9 实现添加到混合中,您会得到 YARV、Red Sun、HotRuby 和 Cardinal,所有这些都使用字节码。 Red Sun 和 HotRuby 甚至要求能够预编译 Ruby 代码,因为它们在 webbrowser 中运行字节码 VM,在 webserver 上运行编译器,因此它们必须能够在服务器上编译代码,将其转储到磁盘,将其下载到浏览器中并再次将其加载到 VM 中。
            【解决方案10】:

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

            【讨论】:

              【解决方案11】:

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

              据我所知,无法通过命令行实际获取字节码。

              【讨论】:

                猜你喜欢
                • 2014-05-10
                • 2012-04-19
                • 2013-06-08
                • 2021-04-22
                • 1970-01-01
                • 1970-01-01
                • 2014-01-16
                • 2016-09-11
                • 1970-01-01
                相关资源
                最近更新 更多