盡管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(InfoQ已經就Cuby/Garnet采訪了Evan Phoenix)的類似方法。
現在,對於JRuby來說,你想使用何種代碼生成方式呢?