fastruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/LICENSE +674 -0
- data/README +142 -0
- data/Rakefile +47 -0
- data/TODO +31 -0
- data/benchmarks/benchmark.rb +68 -0
- data/benchmarks/benchmark2.rb +70 -0
- data/benchmarks/benchmark3.rb +70 -0
- data/benchmarks/benchmark4.rb +94 -0
- data/benchmarks/benchmark5.rb +80 -0
- data/benchmarks/benchmark6.rb +64 -0
- data/examples/example1.rb +12 -0
- data/examples/example2.rb +14 -0
- data/examples/example3.rb +12 -0
- data/examples/example4.rb +17 -0
- data/lib/fastruby/builder.rb +97 -0
- data/lib/fastruby/exceptions.rb +24 -0
- data/lib/fastruby/getlocals.rb +47 -0
- data/lib/fastruby/inline_extension.rb +87 -0
- data/lib/fastruby/logging.rb +37 -0
- data/lib/fastruby/object.rb +168 -0
- data/lib/fastruby/translator.rb +903 -0
- data/lib/fastruby.rb +24 -0
- data/spec/base_spec.rb +357 -0
- data/spec/block_spec.rb +418 -0
- data/spec/control_spec.rb +71 -0
- data/spec/expression_spec.rb +59 -0
- data/spec/integrity_spec.rb +74 -0
- data/spec/literal_spec.rb +95 -0
- data/spec/variable_spec.rb +63 -0
- metadata +127 -0
data/README
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
= Fastruby - fast execution of ruby code
|
2
|
+
|
3
|
+
Fastruby is a gem which allows to execute ruby code faster than normal (about 100X of the MRI1.8)
|
4
|
+
|
5
|
+
Fastruby IS NOT a separated ruby interpreter. Then, the design is simple
|
6
|
+
|
7
|
+
Fastruby IS NOT a DSL to generate C code using ruby or a Ruby to C translator, the goal of fastruby is to execute RUBY code
|
8
|
+
|
9
|
+
*************************************************************************************************************
|
10
|
+
|
11
|
+
The current version of fastruby is a Proof of Concept and it's not ready to go to production
|
12
|
+
|
13
|
+
*************************************************************************************************************
|
14
|
+
|
15
|
+
== Core Concepts
|
16
|
+
|
17
|
+
=== Native build
|
18
|
+
|
19
|
+
All code processed by fastruby ends with a native representation, in the current version, this is acomplished using RubyParser to parse rubycode.
|
20
|
+
The ruby code is translated to C and then processed with RubyInline
|
21
|
+
|
22
|
+
=== Transparent multimethods (and multiblocks)
|
23
|
+
|
24
|
+
The methods processed by fastruby has multiple internal implementations depending on the type of the arguments.
|
25
|
+
Each possible signature has a version of the method and this are built in runtime when the method is called with a new signature.
|
26
|
+
The same concept will be applied to blocks (anonymous methods) in future releases
|
27
|
+
|
28
|
+
=== Type inference
|
29
|
+
|
30
|
+
Each version of a method is built for a specific signature, so, the builder can asume a type for the arguments and build method calls using that assumption.
|
31
|
+
Whereever the translator can asume a type for a expression involved in a method call (used as argument or as receiver), this information can be used to encode
|
32
|
+
direct calls instead of normal and expensive ruby calls.
|
33
|
+
|
34
|
+
The currently implementation only can infer types for method and block arguments, and for literals
|
35
|
+
|
36
|
+
=== Customization through build directives and API
|
37
|
+
|
38
|
+
To compensate for the described limitations, fastruby suport a few build directives to allow the programmer help the inference.
|
39
|
+
The syntaxis of these directives are the same as normal ruby call (see examples)
|
40
|
+
Also, fastruby will define a API to customize aspects of fastruby internals. E.g the build method to invoke the build of methods with a specific signature (see examples)
|
41
|
+
|
42
|
+
== Installation
|
43
|
+
|
44
|
+
The install is as simple as execute the well-known gem install:
|
45
|
+
|
46
|
+
sudo gem install fastruby
|
47
|
+
|
48
|
+
== Documentation
|
49
|
+
|
50
|
+
Since this first version of fastruby is in part an spike/PoC, there is no stable API to document.
|
51
|
+
So, I recommend not to develop other software on top of fastruby since its API could change in any moment.
|
52
|
+
But I will try as much as possible keep the backward compatibility in the near future
|
53
|
+
|
54
|
+
I will stabilize the API and document it for next releases. I promise
|
55
|
+
|
56
|
+
== Known Limitations & Issues
|
57
|
+
|
58
|
+
* fastruby only can be called from inside a class scope, and only can be used to define instance methods (no class methods)
|
59
|
+
* fastruby invokations can't take more than one method
|
60
|
+
* monkey patching does not work with fastruby methods
|
61
|
+
* calls with blocks to ruby or cruby methods are almost as slow as normal ruby (if the called method is defined by fastruby, the call it's pretty fast)
|
62
|
+
* does not support singleton methods (both define & call)
|
63
|
+
* does not support methods with variable number of arguments
|
64
|
+
* does not support exception handling (rescue, ensure, etc...)
|
65
|
+
|
66
|
+
== Usage
|
67
|
+
|
68
|
+
The basic method is fastruby, fastruby takes a string with ruby code and compile it
|
69
|
+
|
70
|
+
=== Example 1: How invoke fastruby
|
71
|
+
|
72
|
+
require "fastruby"
|
73
|
+
|
74
|
+
class X
|
75
|
+
fastruby '
|
76
|
+
def foo
|
77
|
+
print "hello world\n"
|
78
|
+
end
|
79
|
+
'
|
80
|
+
end
|
81
|
+
|
82
|
+
X.new.foo
|
83
|
+
|
84
|
+
=== Example 2: Prebuild
|
85
|
+
|
86
|
+
Normally, the method is built at runtime when is called with a new signature, You can prebuild the method to prevent this when the method is called for first time
|
87
|
+
|
88
|
+
require "fastruby"
|
89
|
+
|
90
|
+
class X
|
91
|
+
fastruby '
|
92
|
+
def foo(a,b)
|
93
|
+
a+b
|
94
|
+
end
|
95
|
+
'
|
96
|
+
end
|
97
|
+
|
98
|
+
X.build([X,String,String] , :foo)
|
99
|
+
|
100
|
+
p X.new.foo("fast", "ruby") # will use the prebuilded method
|
101
|
+
p X.new.foo(["fast"], ["ruby"]) # will build foo for X,Array,Array signature and then execute it
|
102
|
+
|
103
|
+
=== Example 3: Explicit inference
|
104
|
+
|
105
|
+
Current fastruby allows to explictly define a type for a expression, a basic example show as tell to fastruby to assume that the result of to_s is of type String in the following case:
|
106
|
+
|
107
|
+
require "fastruby"
|
108
|
+
|
109
|
+
class X
|
110
|
+
fastruby '
|
111
|
+
def foo(a)
|
112
|
+
a.to_s.infer(String) + "_"
|
113
|
+
end
|
114
|
+
'
|
115
|
+
end
|
116
|
+
|
117
|
+
p X.new.foo(9)
|
118
|
+
|
119
|
+
When fastruby can infer the type of an expression, the method calls that involve that expression can be accelerated. This is not necessary for arguments passed to a method or block
|
120
|
+
|
121
|
+
=== Example 4: Variable types
|
122
|
+
|
123
|
+
Like static languages, you can define a type for a variable to help the inference and gain some performance. This can be done by using lvar_type directive
|
124
|
+
|
125
|
+
class X
|
126
|
+
fastruby '
|
127
|
+
def foo
|
128
|
+
lvar_type(i, Fixnum)
|
129
|
+
i = 100
|
130
|
+
while (i > 0)
|
131
|
+
i = i - 1
|
132
|
+
end
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
'
|
136
|
+
end
|
137
|
+
|
138
|
+
With no lvar_type, the calls to Fixnum#> and Fixnum#- will be dynamic and more expensive
|
139
|
+
|
140
|
+
== Copying
|
141
|
+
|
142
|
+
Copyright (c) 2011 Dario Seminara, released under the GPL License (see LICENSE)
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
|
8
|
+
spec = Gem::Specification.new do |s|
|
9
|
+
s.name = 'fastruby'
|
10
|
+
s.version = '0.0.1'
|
11
|
+
s.author = 'Dario Seminara'
|
12
|
+
s.email = 'robertodarioseminara@gmail.com'
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.summary = 'fast execution of ruby code'
|
15
|
+
s.homepage = "http://github.com/tario/fastruby"
|
16
|
+
s.add_dependency "RubyInline", "= 3.9.0"
|
17
|
+
s.add_dependency "ruby_parser", "= 2.0.6"
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.extra_rdoc_files = [ 'README' ]
|
20
|
+
# s.rdoc_options << '--main' << 'README'
|
21
|
+
s.files = Dir.glob("{benchmarks,examples,lib,spec}/**/*") +
|
22
|
+
[ 'LICENSE', 'AUTHORS', 'README', 'Rakefile', 'TODO' ]
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Run tests'
|
26
|
+
|
27
|
+
RSpec::Core::RakeTask.new("test:units") do |t|
|
28
|
+
t.pattern= 'spec/**/*.rb'
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Generate RDoc'
|
32
|
+
Rake::RDocTask.new :rdoc do |rd|
|
33
|
+
rd.rdoc_dir = 'doc'
|
34
|
+
rd.rdoc_files.add 'lib', 'README'
|
35
|
+
rd.main = 'README'
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'Build Gem'
|
39
|
+
Rake::GemPackageTask.new spec do |pkg|
|
40
|
+
pkg.need_tar = true
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'Clean up'
|
44
|
+
task :clean => [ :clobber_rdoc, :clobber_package ]
|
45
|
+
|
46
|
+
desc 'Clean up'
|
47
|
+
task :clobber => [ :clean ]
|
data/TODO
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Basic functionality:
|
2
|
+
|
3
|
+
* Flow control setences: case
|
4
|
+
* Exceptions
|
5
|
+
* Defining and call of methods with variable number of arguments
|
6
|
+
* Blocks with variable number of arguments
|
7
|
+
* call to monkey patched methods from fastruby code
|
8
|
+
* callcc
|
9
|
+
|
10
|
+
To improve:
|
11
|
+
|
12
|
+
* Inlining of methods
|
13
|
+
* Error check (e.g. calling a directive with invalid parameters)
|
14
|
+
* Fastruby builds himself to improve performance of dynamic builds
|
15
|
+
* Multiblocks
|
16
|
+
* Fastruby method allow defining many methods in only one call and allow define classes
|
17
|
+
* Oracle testing using normal ruby as oracle
|
18
|
+
* Inference using "return types" of methods when the implementation of the method is known
|
19
|
+
* RubySpec: make code executed by fastruby pass RubySpec
|
20
|
+
|
21
|
+
Refactor:
|
22
|
+
|
23
|
+
* hashes of methods on builder refactored into an only hash
|
24
|
+
* refactor anonoymous methods (tip: use ruby format string for names)
|
25
|
+
* Clean of duplicated code
|
26
|
+
* Remove ruby inline explicit dependency
|
27
|
+
|
28
|
+
Documentation:
|
29
|
+
|
30
|
+
* Builder directives
|
31
|
+
* Build API
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class X
|
5
|
+
fastruby "
|
6
|
+
def foo(a,b)
|
7
|
+
return a+b
|
8
|
+
end
|
9
|
+
"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Y
|
13
|
+
fastruby "
|
14
|
+
def bar(x)
|
15
|
+
i = 1000000
|
16
|
+
|
17
|
+
lvar_type(i,Fixnum)
|
18
|
+
|
19
|
+
ret = 0
|
20
|
+
while i > 0
|
21
|
+
ret = x.foo(i,i)
|
22
|
+
i = i - 1
|
23
|
+
end
|
24
|
+
return ret
|
25
|
+
end
|
26
|
+
|
27
|
+
"
|
28
|
+
end
|
29
|
+
|
30
|
+
class X2
|
31
|
+
def foo(a,b)
|
32
|
+
return a+b
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Y2
|
37
|
+
def bar(x)
|
38
|
+
i = 1000000
|
39
|
+
ret = 0
|
40
|
+
while i > 0
|
41
|
+
ret = x.foo(i,i)
|
42
|
+
i = i - 1
|
43
|
+
end
|
44
|
+
return ret
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
x = X.new
|
51
|
+
y = Y.new
|
52
|
+
y2 = Y2.new
|
53
|
+
x2 = X2.new
|
54
|
+
|
55
|
+
Y.build([Y,X],:bar)
|
56
|
+
|
57
|
+
require 'benchmark'
|
58
|
+
|
59
|
+
Benchmark::bm(20) do |b|
|
60
|
+
|
61
|
+
b.report("fastruby") do
|
62
|
+
y.bar(x)
|
63
|
+
end
|
64
|
+
|
65
|
+
b.report("ruby") do
|
66
|
+
y2.bar(x2)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class X
|
5
|
+
fastruby "
|
6
|
+
def foo
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Y
|
13
|
+
fastruby "
|
14
|
+
def bar(x)
|
15
|
+
i = 1000000
|
16
|
+
|
17
|
+
lvar_type(i,Fixnum)
|
18
|
+
|
19
|
+
ret = 0
|
20
|
+
while i > 0
|
21
|
+
x.foo do
|
22
|
+
end
|
23
|
+
i = i - 1
|
24
|
+
end
|
25
|
+
0
|
26
|
+
end
|
27
|
+
|
28
|
+
"
|
29
|
+
end
|
30
|
+
|
31
|
+
class X2
|
32
|
+
def foo
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Y2
|
38
|
+
def bar(x)
|
39
|
+
i = 1000000
|
40
|
+
|
41
|
+
ret = 0
|
42
|
+
while i > 0
|
43
|
+
x.foo do
|
44
|
+
i = i - 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
x = X.new
|
53
|
+
y = Y.new
|
54
|
+
y2 = Y2.new
|
55
|
+
x2 = X2.new
|
56
|
+
|
57
|
+
Y.build([Y,X],:bar)
|
58
|
+
|
59
|
+
require 'benchmark'
|
60
|
+
|
61
|
+
Benchmark::bm(20) do |b|
|
62
|
+
|
63
|
+
b.report("fastruby") do
|
64
|
+
y.bar(x)
|
65
|
+
end
|
66
|
+
|
67
|
+
b.report("ruby") do
|
68
|
+
y2.bar(x2)
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class X
|
5
|
+
fastruby "
|
6
|
+
def foo
|
7
|
+
yield(1,2,3)
|
8
|
+
end
|
9
|
+
"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Y
|
13
|
+
fastruby "
|
14
|
+
def bar(x)
|
15
|
+
i = 1000000
|
16
|
+
|
17
|
+
lvar_type(i,Fixnum)
|
18
|
+
|
19
|
+
ret = 0
|
20
|
+
while i > 0
|
21
|
+
x.foo do |a,b,c|
|
22
|
+
end
|
23
|
+
i = i - 1
|
24
|
+
end
|
25
|
+
0
|
26
|
+
end
|
27
|
+
|
28
|
+
"
|
29
|
+
end
|
30
|
+
|
31
|
+
class X2
|
32
|
+
def foo
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Y2
|
38
|
+
def bar(x)
|
39
|
+
i = 1000000
|
40
|
+
|
41
|
+
ret = 0
|
42
|
+
while i > 0
|
43
|
+
x.foo do
|
44
|
+
i = i - 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
x = X.new
|
53
|
+
y = Y.new
|
54
|
+
y2 = Y2.new
|
55
|
+
x2 = X2.new
|
56
|
+
|
57
|
+
Y.build([Y,X],:bar)
|
58
|
+
|
59
|
+
require 'benchmark'
|
60
|
+
|
61
|
+
Benchmark::bm(20) do |b|
|
62
|
+
|
63
|
+
b.report("fastruby") do
|
64
|
+
y.bar(x)
|
65
|
+
end
|
66
|
+
|
67
|
+
b.report("ruby") do
|
68
|
+
y2.bar(x2)
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class Y
|
5
|
+
fastruby "
|
6
|
+
def bar
|
7
|
+
i = 1000000
|
8
|
+
|
9
|
+
lvar_type(i,Fixnum)
|
10
|
+
|
11
|
+
ret = 0
|
12
|
+
while i > 0
|
13
|
+
$a = 9
|
14
|
+
i = i - 1
|
15
|
+
end
|
16
|
+
0
|
17
|
+
end
|
18
|
+
|
19
|
+
"
|
20
|
+
end
|
21
|
+
|
22
|
+
class Y2
|
23
|
+
def bar
|
24
|
+
i = 1000000
|
25
|
+
|
26
|
+
ret = 0
|
27
|
+
while i > 0
|
28
|
+
$a = 9
|
29
|
+
i = i - 1
|
30
|
+
end
|
31
|
+
0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
class Y_
|
37
|
+
fastruby "
|
38
|
+
def bar
|
39
|
+
i = 1000000
|
40
|
+
|
41
|
+
lvar_type(i,Fixnum)
|
42
|
+
|
43
|
+
ret = 0
|
44
|
+
while i > 0
|
45
|
+
i = i - 1
|
46
|
+
end
|
47
|
+
0
|
48
|
+
end
|
49
|
+
|
50
|
+
"
|
51
|
+
end
|
52
|
+
|
53
|
+
class Y2_
|
54
|
+
def bar
|
55
|
+
i = 1000000
|
56
|
+
|
57
|
+
ret = 0
|
58
|
+
while i > 0
|
59
|
+
i = i - 1
|
60
|
+
end
|
61
|
+
0
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
y = Y.new
|
67
|
+
y2 = Y2.new
|
68
|
+
y_ = Y_.new
|
69
|
+
y2_ = Y2_.new
|
70
|
+
|
71
|
+
Y.build([Y],:bar)
|
72
|
+
Y_.build([Y_],:bar)
|
73
|
+
|
74
|
+
require 'benchmark'
|
75
|
+
|
76
|
+
Benchmark::bm(20) do |b|
|
77
|
+
|
78
|
+
b.report("fastruby") do
|
79
|
+
y.bar
|
80
|
+
end
|
81
|
+
|
82
|
+
b.report("ruby") do
|
83
|
+
y2.bar
|
84
|
+
end
|
85
|
+
|
86
|
+
b.report("lfastruby") do
|
87
|
+
y_.bar
|
88
|
+
end
|
89
|
+
|
90
|
+
b.report("lruby") do
|
91
|
+
y2_.bar
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class X
|
5
|
+
fastruby "
|
6
|
+
def bar
|
7
|
+
end
|
8
|
+
"
|
9
|
+
|
10
|
+
fastruby "
|
11
|
+
def foo
|
12
|
+
yield(self)
|
13
|
+
end
|
14
|
+
"
|
15
|
+
end
|
16
|
+
|
17
|
+
class Y
|
18
|
+
fastruby "
|
19
|
+
def bar(x)
|
20
|
+
i = 1000000
|
21
|
+
|
22
|
+
lvar_type(i,Fixnum)
|
23
|
+
|
24
|
+
x2 = 0
|
25
|
+
ret = 0
|
26
|
+
while i > 0
|
27
|
+
x.foo do |x2|
|
28
|
+
x2.bar
|
29
|
+
end
|
30
|
+
i = i - 1
|
31
|
+
end
|
32
|
+
0
|
33
|
+
end
|
34
|
+
|
35
|
+
"
|
36
|
+
end
|
37
|
+
|
38
|
+
class X2
|
39
|
+
def bar
|
40
|
+
end
|
41
|
+
|
42
|
+
def foo
|
43
|
+
yield(self)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Y2
|
48
|
+
def bar(x)
|
49
|
+
i = 1000000
|
50
|
+
|
51
|
+
ret = 0
|
52
|
+
while i > 0
|
53
|
+
x.foo do |x2|
|
54
|
+
x2.bar
|
55
|
+
end
|
56
|
+
i = i - 1
|
57
|
+
end
|
58
|
+
0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
x = X.new
|
64
|
+
y = Y.new
|
65
|
+
y2 = Y2.new
|
66
|
+
x2 = X2.new
|
67
|
+
|
68
|
+
Y.build([Y,X],:bar)
|
69
|
+
|
70
|
+
require 'benchmark'
|
71
|
+
|
72
|
+
Benchmark::bm(20) do |b|
|
73
|
+
b.report("fastruby") do
|
74
|
+
y.bar(x)
|
75
|
+
end
|
76
|
+
|
77
|
+
b.report("ruby") do
|
78
|
+
y2.bar(x2)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "fastruby"
|
3
|
+
|
4
|
+
class X
|
5
|
+
fastruby '
|
6
|
+
def foo
|
7
|
+
"65535".to_i
|
8
|
+
end
|
9
|
+
'
|
10
|
+
end
|
11
|
+
|
12
|
+
class Y
|
13
|
+
fastruby "
|
14
|
+
def bar(x)
|
15
|
+
i = 1000000
|
16
|
+
lvar_type(i,Fixnum)
|
17
|
+
|
18
|
+
while i > 0
|
19
|
+
x.foo
|
20
|
+
i = i - 1
|
21
|
+
end
|
22
|
+
0
|
23
|
+
end
|
24
|
+
|
25
|
+
"
|
26
|
+
end
|
27
|
+
|
28
|
+
class X2
|
29
|
+
def foo
|
30
|
+
"65535".to_i
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Y2
|
35
|
+
def bar(x)
|
36
|
+
i = 1000000
|
37
|
+
|
38
|
+
while i > 0
|
39
|
+
x.foo
|
40
|
+
i = i - 1
|
41
|
+
end
|
42
|
+
0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
x = X.new
|
48
|
+
y = Y.new
|
49
|
+
y2 = Y2.new
|
50
|
+
x2 = X2.new
|
51
|
+
|
52
|
+
Y.build([Y,X],:bar)
|
53
|
+
|
54
|
+
require 'benchmark'
|
55
|
+
|
56
|
+
Benchmark::bm(20) do |b|
|
57
|
+
b.report("fastruby") do
|
58
|
+
y.bar(x)
|
59
|
+
end
|
60
|
+
|
61
|
+
b.report("ruby") do
|
62
|
+
y2.bar(x2)
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "fastruby"
|
2
|
+
|
3
|
+
class X
|
4
|
+
fastruby '
|
5
|
+
def foo(a,b)
|
6
|
+
a+b
|
7
|
+
end
|
8
|
+
'
|
9
|
+
end
|
10
|
+
|
11
|
+
X.build([X,String,String] , :foo)
|
12
|
+
|
13
|
+
p X.new.foo("fast", "ruby") # will use the prebuilded method
|
14
|
+
p X.new.foo(["fast"], ["ruby"]) # will build foo for X,Array,Array signature and then execute it
|