论坛首页 编程语言技术论坛

使用JRuby生成JVM代码

浏览 1354 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2008-04-03  

尽管JRuby的性能已经接近CRuby了,但有时它仍然不够快。CRuby的用户可以使用Ryan Davis的RubyInline库,它提供了对C/C++的内建支持以便更容易的产生Ruby的C扩展。来自JRuby阵营的Charles Nutter现在已经为JRuby实现了一个RubyInline builder ,它可以即时编译嵌入的Java代码。

下面是Ryan Davis提供的使用C编写的一个阶乘计算方法的示例

class MyTest
 inline do |builder|
 builder.c "
  long factorial_c(int max) {
   int i=max, result=1; 
   while (i >= 2) { result *= i--; }    
   return result;     
  }
 "
 end
end 

下面是Charles提供的相应的JRuby实现

class FastMath
 inline :Java do |builder|
   builder.package "org.jruby.test" 
   builder.java "
   public static long factorial_java(int max) {
    int i=max, result=1;
    while (i >= 2) { result *= i--; } 
    return result;       
   }
   "
 end
end  

RubyInline for JRuby的一个缺点在于其需要Java 6 JDK(对于编译器),它可能还无法在所有系统上都可使用。

另一个可产生快速执行代码的方法就是直接产生JVM字节码。对于正常的应用来说,这听起来有些过激了,像编译器这样的字节码生成工具会从一个简单的字节码生成DSL中获益,就像早前Charles Nutter的博客中提到的那样。然而即便通过DSL来生成字节码也并非易事。以下是Charles的博客中的一个例子:一个名为bar的方法将小写的String参数加到传进来的ArrayList中,下面就是产生的代码:

def test_class_builder
 cb = Compiler::ClassBuilder.build("MyClass", "MyClass.java") do
 [...]     
 method(:bar, ArrayList, String, ArrayList) do
  aload 1  
  invokevirtual(String, :toLowerCase, String)  
  aload 2       
  swap
  invokevirtual(ArrayList, :add, [Boolean::TYPE, Object])   
  aload 2     
  areturn
end
[...]  

Charles Nutter还提供了一个新方案,这就是叫做Duby的新语言,它实现了Ruby语法的一个子集,增强了一些类型推断逻辑(请访问Charles的博客来了解更多信息),以此来生成快速的字节码。下面同样是计算阶乘的方法,这次是针对Duby编译器而写的。

class Fac
 def self.fac(max)
  {max => :int, :return => :int}
  i = max
  result = 1
  while i > 1
   result *= i
   i -= 1 
  end
  result
 end
end 

这是一个原型,用来展现以一种类Ruby语言而不是一种新语言来实现类型推断的可能性。它还可被JRuby程序员所用,以避免因为性能问题而回退到Java,或者用来实现JRuby本身的一些部分功能,这与Squeak Smalltalk的Slang很像,它是Smalltalk语言的一个子集,可以很轻易的转化为C。Rubinius计划使用叫做Garnet的类似方法。现在,对于JRuby来说,你想使用何种代码生成方式呢?

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics