【问题标题】:Convert Ruby to low level languages?将 Ruby 转换为低级语言?
【发布时间】:2010-08-22 19:25:30
【问题描述】:

我有各种用 Ruby 编写的脚本:

rails (symfony)
ruby (php, bash)
rb-appscript (applescript)

是否也可以用 Ruby 替换低级语言?

我用 Ruby 编写,它会将其转换为 java、c++ 或 c。

原因人们说,当涉及到 Ruby 中对性能更为关键的任务时,您可以使用 C 对其进行扩展。但是扩展一词意味着您编写的 C 文件只需在 Ruby 代码中调用。我想知道,我是否可以改用 Ruby 并将其转换为 C 源代码,然后将其编译为机器代码。然后我可以用 C 语言“扩展”它,但用 Ruby 代码。

这就是这篇文章的内容。用 Ruby 编写一切,但获得 C(或 Java)的性能。

第二个优点是您不必学习其他语言。

就像 PHP 的 HipHop。

有这方面的实现吗?

【问题讨论】:

  • khm、Java 和 C# 不是低级语言 :)
  • Nikita:Alan Perlis 说“当它的程序需要关注不相关的东西时,编程语言是低级的”。作为一个用 Java 和 C# 以及低级和高级语言编写多年的人,我确实将这两种语言称为低级。 (在我看来,C#4 会敲 HLL-hood 的大门,除非它变得如此复杂以至于需要注意其复杂性本身可能会导致它不符合 Perlis 的标准。)它真的与程序员相关吗每次需要 5 行时重新实现 lambda?
  • @Ken 我曾经认为高级语言可以让你从了解计算机的细节及其工作原理中解放出来。从这个意义上说,函数式、过程式和 OO 语言都可以是高级语言。非常复杂的语言(如 Ada)仍然可以是高级的。至于 Alan Perlis,这句话有点含糊,没有上下文很难说出他的意思。
  • Nikita:我同意函数式、过程式和 OO 语言可以是高级语言,我已经使用了所有这些的好例子。我还是不能板着脸说“Java是一门高级语言”。 :-)

标签: ruby


【解决方案1】:

这样的编译器将是一项巨大的工作。就算成功了,还是得去

  1. 包括 ruby​​ 运行时
  2. 包括标准库(不是为了性能而构建的,而是为了可用性)
  3. 允许元编程
  4. 做动态调度

所有这些都会造成巨大的运行时损失,因为 C 编译器既无法理解也无法优化此类抽象。 Ruby 和其他动态语言不仅速度较慢,因为它们被解释(或编译为字节码,然后被解释),而且因为它们是动态的。

示例

在 C++ 中,大多数情况下可以内联方法调用,因为编译器知道 this 的确切类型。如果传递了子类型,则方法仍然不能更改,除非它是虚拟的,在这种情况下使用仍然非常有效的查找表。

在 Ruby 中,类和方法可以随时以任何方式更改,因此每次都需要(相对昂贵的)查找。

像 Ruby、Python 或 Perl 这样的语言有很多特性昂贵的,而且大多数相关程序都严重依赖这些特性(当然,它们非常有用!),所以它们不能被删除或内联。

简单地说:动态语言很难优化,只是做解释器会做的事情,然后将其编译成机器代码并不能解决问题。正如 V8 所证明的那样,从动态语言中获得令人难以置信的速度是可能的,但您必须投入大量资金和充满聪明程序员的办公室。

【讨论】:

  • @Dorian 我写的(两年前-.-)仍然正确。 JIT 编译器至少在某些时候回避了我提到的问题,但这并没有使问题变得不那么重要。 AOT 编译,这就是这个问题和我的回答所涉及的,在优化动态语言方面仍然并且将永远无效。
  • 现在有一个实验性的“Sorbet Compiler”,可以从 Ruby 代码生成本机扩展。
【解决方案2】:

https://github.com/seattlerb/ruby_to_c Ruby To C 编译器。它实际上只接受了 Ruby 的一个子集。我认为主要的缺失部分是元编程功能

【讨论】:

  • 它是一个从 Ruby 到 C 的转换器,然后将 C 源代码编译为二进制吗?
  • ruby2c 的链接坏了,但是我已经开始a similar project with the same purpose了。
  • 链接不再可用
  • 我认为这是 Github 上的同一个项目:github.com/seattlerb/ruby_to_c
  • @AndersonGreen 它支持什么语言?从存储库自述文件看来,它目前只能从 Javascript 转换为 Java?
【解决方案3】:

在最近的一次采访中(2012 年 11 月 16 日)Yukihiro "Matz" Matsumoto(Ruby 的创建者)谈到了将 Ruby 编译为 C

(...) 在东京大学,一名研究生正在从事一项学术研究项目,该项目在编译二进制代码之前将 Ruby 代码编译为 C 代码。该过程涉及类型推断等技术,在最佳场景下,速度可以达到典型手写 C 代码的 90%。到目前为止只发表了一篇论文,还没有开源代码,但我希望明年一切都会揭晓……(from interview)

只有一个学生并不多,但这可能是一个有趣的项目。要完全支持 Ruby 可能还有很长的路要走。

【讨论】:

  • 现在是 2017 年!项目发生了什么?
  • @Anwar 最有可能?现实。
【解决方案4】:

“低级别”是高度主观的。许多人的界限不同,所以为了这个论点,我只是假设您的意思是将 Ruby 编译为中间形式,然后可以将其转换为特定平台的机器代码。即,将 ruby​​ 编译为 C 或 LLVM IR,或类似的东西。

简短的回答是肯定的,这是可能的。

更长的答案是这样的:

几种语言(尤其是Objective-C)作为其他语言的薄层存在。出于所有实际目的,ObjC 语法实际上只是对 objc_*() libobjc 运行时调用的松散包装。

知道了这一点,那么编译器会做什么呢?嗯,它基本上像任何 C 编译器一样工作,但也接受 objc 特定的东西,并生成适当的 C 函数调用以与 objc 运行时交互。

可以用类似的方式实现 ruby​​ 编译器。

然而,还应该注意的是,仅仅将一种语言转换为较低级别的形式并不意味着语言会立即表现得更好,但这并不意味着它也会表现得更差。你真的必须问自己为什么要这样做,如果这是一个很好的理由。

【讨论】:

  • @jer。人们说,当涉及到 Ruby 中更关键的性能任务时,您可以使用 C 对其进行扩展。但是扩展这个词意味着您编写的 C 文件只需在 Ruby 代码中调用。我想知道,我是否可以改用 Ruby 并将其转换为 C 源代码,然后将其编译为机器代码。然后我可以用 C 语言“扩展”它,但用 Ruby 代码。这就是这篇文章的内容。用 Ruby 编写一切,但获得 C(或 Java)的性能。
  • @ajsie: 一个(任何)编译器都需要非常聪明地在任何地方生成代码,就像用[目标语言]编写的扩展一样高效(通过一个好的[目标语言]程序员)。如今,C/C++ 编译器非常聪明,因此在 90% 的情况下它们击败了 90% 的汇编程序员,但它们有几个世纪的时间和许多大公司的支持才能走到这一步。但是任何一个开源团队可能在 10 年内生产的 Ruby->C 编译器仍然落后于编写良好的 C。
  • @ajsie:您在第一个上下文中所说的“扩展”是我们语言中的人们倾向于称之为“绑定”的意思。此外,第二种情况下的“扩展”被称为“FFI”。 Ruby 确实提供了绑定,但没有内置 FFI(不过有相应的库),这可以让您与 C 代码进行交互。
  • @jer:我现在太累了,无法仔细检查(在德国这里几乎是凌晨 4:00,我刚刚完成令人毛骨悚然的 8 小时轮班回家),但我认为截至Ruby 1.9.2,FFI 是标准库的一部分。
  • @Jörg:很可能,说实话,我还没有太关注 1.9 分支。 Ruby 不再是我开发的主要语言,所以有时很难找到时间跟上新的发展。
【解决方案5】:

还有JRuby,如果您仍然认为Java 是一种低级语言。实际上,语言本身在这里并没有多大关系:可以编译成 JVM 字节码,这与语言无关。

【讨论】:

  • 这会解决人们正在解决的性能问题“您可以使用 C/Java 扩展 Ruby”吗?
  • 你不是在这里扩展(不是在你现有的 Ruby 代码中添加这些语言的功能),而是在不同的虚拟机中运行你的代码。是的,据说 JRuby 比 MRI(ruby 1.8 的虚拟机)运行得更快。~)。但是,Ruby VM 还有其他一些实现,1.9.1 承诺会更快。我没有对自己进行基准测试,但您可以搜索一些不同 Ruby 实现的速度比较。 JRuby 是最快的之一。
【解决方案6】:

性能不仅仅来自“低级”编译语言。将您的 Ruby 程序交叉编译为复杂的、自动生成的 C 代码也无济于事。这可能会让事情变得混乱,包括编译时间长等。还有更好的方法。

但你先说“低级语言”,然后再提到 Java。 Java 不是低级语言。就高级或低级语言而言,它仅比 Ruby 低一级。但是,如果您查看 Java 的工作原理、JVM、字节码和即时编译,您就会看到高级语言的速度有多快(呃)。 Ruby 目前正在做类似的事情。 MRI 1.8 是一种解释性语言,存在一些性能问题。 1.9 更快,它使用字节码解释器。我不确定它是否会在 MRI 上发生,但 Ruby 距离 MRI 上的 JIT 仅一步之遥。

我不确定 jRuby 和 IronRuby 背后的技术,但他们可能已经在这样做了。但是,两者都有自己的优点和缺点。我倾向于坚持使用 MRI,它足够快而且效果很好。

【讨论】:

    【解决方案7】:

    设计一个将 Ruby 源代码转换为 C++ 的编译器可能是可行的。 Ruby 程序可以使用 unholy 编译器编译成 Python,因此它们可以使用 Nuitka 编译器从 Python 编译成 C++。

    unholy 编译器是十多年前开发的,但它可能仍适用于当前版本的 Python。

    Ruby2Cextension 是另一个将 Ruby 的子集转换为 C++ 的编译器,尽管它自 2008 年以来一直没有更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 2019-12-12
      • 2015-01-23
      • 2021-03-14
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多