forked from jruby/jruby
/
test_fib_compiler.rb
121 lines (105 loc) · 2.77 KB
/
test_fib_compiler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
require 'java'
require 'jruby'
include_class "org.jruby.ast.executable.InstructionCompiler2"
include_class "java.io.FileOutputStream"
include_class "org.jruby.util.JRubyClassLoader"
include_class "org.jruby.runtime.builtin.IRubyObject"
compiler = InstructionCompiler2.new();
# pure ruby version
def fib_ruby(n)
if n < 2
n
else
fib_ruby(n - 2) + fib_ruby(n - 1)
end
end
# version to be parsed and compiled
fib_java_str = <<EOS
def fib_java(n)
if n < 2
n
else
fib_java(n - 2) + fib_java(n - 1)
end
end
def fib_iter_java(n)
i = 0
j = 1
cur = 1
while cur <= n
k = i
i = j
j = k + j
cur = cur + 1
end
i
end
def comp_test
begin
nil
1111111111111111111111111111111111111111111111111111111111
1.0
false
true
[1, 2, 3, 4, 5]
"hello"
x = 1
while (x < 5)
puts x
x = x + 1
end
@@x = 5
p @@x
end
end
EOS
def fib_iter_ruby(n)
i = 0
j = 1
cur = 1
while cur <= n
k = i
i = j
j = k + j
cur = cur + 1
end
i
end
# parse and compile
fib_java_n = JRuby.parse(fib_java_str, __FILE__);
begin
class_and_method = compiler.compile("MyCompiledScript", __FILE__, fib_java_n);
rescue Exception => e
puts e
exit(1)
end
# create the classloader
script_class_loader = JRubyClassLoader.new
# write it out, just for fun
classes = {}
compiler.class_writers.each do |k,v|
FileOutputStream.new("#{k}.class").write(v.to_byte_array())
classes[k] = script_class_loader.define_class(k, v.to_byte_array())
end
# bind method to Kernel#fib_java
script_class = classes["MyCompiledScript$MultiStub0"]
stub = script_class.newInstance
compiler.define_module_function(JRuby.runtime, "Kernel", "fib_java", stub, 1, org.jruby.runtime.Arity.singleArgument, org.jruby.runtime.Visibility::PUBLIC);
compiler.define_module_function(JRuby.runtime, "Kernel", "fib_iter_java", stub, 2, org.jruby.runtime.Arity.singleArgument, org.jruby.runtime.Visibility::PUBLIC);
compiler.define_module_function(JRuby.runtime, "Kernel", "comp_test", stub, 3, org.jruby.runtime.Arity.noArguments, org.jruby.runtime.Visibility::PUBLIC);
# a simple benchmarking function
def time(str)
t = Time.now
yield
puts "Time for #{str}: #{Time.now - t}"
end
p comp_test(nil)
# time interpreted versus compiled
time("bi-recursive, interpreted") { fib_ruby(30) }
time("bi-recursive, compiled") { fib_java(30) }
time("bi-recursive, interpreted") { fib_ruby(30) }
time("bi-recursive, compiled") { fib_java(30) }
time("iterative, interpreted") { fib_iter_ruby(500000) }
time("iterative, compiled") { fib_iter_java(500000) }
time("iterative, interpreted") { fib_iter_ruby(500000) }
time("iterative, compiled") { fib_iter_java(500000) }