RubyInlineWithoutZenTest 3.12.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/History.txt +470 -0
- data/LICENSE.txt +22 -0
- data/Manifest.txt +12 -0
- data/README.md +29 -0
- data/README.txt +138 -0
- data/Rakefile +17 -0
- data/demo/fastmath.rb +27 -0
- data/demo/hello.rb +13 -0
- data/example.rb +86 -0
- data/example2.rb +33 -0
- data/lib/inline/mapping.rb +119 -0
- data/lib/inline/version.rb +3 -0
- data/lib/inline.rb +902 -0
- data/rubyinlinewithoutzentest.gemspec +39 -0
- data/test/test_inline.rb +1059 -0
- data/tutorial/example1.rb +63 -0
- data/tutorial/example2.rb +96 -0
- metadata +127 -0
data/demo/fastmath.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
begin require 'rubygems' rescue LoadError end
|
3
|
+
require 'inline'
|
4
|
+
|
5
|
+
class FastMath
|
6
|
+
def factorial(n)
|
7
|
+
f = 1
|
8
|
+
n.downto(2) { |x| f *= x }
|
9
|
+
return f
|
10
|
+
end
|
11
|
+
inline do |builder|
|
12
|
+
builder.c "
|
13
|
+
long factorial_c(int max) {
|
14
|
+
int i=max, result=1;
|
15
|
+
while (i >= 2) { result *= i--; }
|
16
|
+
return result;
|
17
|
+
}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
math = FastMath.new
|
22
|
+
|
23
|
+
if ARGV.empty? then
|
24
|
+
30000.times do math.factorial(20); end
|
25
|
+
else
|
26
|
+
30000.times do math.factorial_c(20); end
|
27
|
+
end
|
data/demo/hello.rb
ADDED
data/example.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
$:.unshift 'lib'
|
5
|
+
require 'inline'
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
FileUtils.rm_rf File.expand_path("~/.ruby_inline")
|
9
|
+
|
10
|
+
class MyTest
|
11
|
+
|
12
|
+
def factorial(n)
|
13
|
+
f = 1
|
14
|
+
n.downto(2) { |x| f *= x }
|
15
|
+
f
|
16
|
+
end
|
17
|
+
|
18
|
+
inline do |builder|
|
19
|
+
builder.c "
|
20
|
+
long factorial_c(int max) {
|
21
|
+
int i=max, result=1;
|
22
|
+
while (i >= 2) { result *= i--; }
|
23
|
+
return result;
|
24
|
+
}"
|
25
|
+
|
26
|
+
builder.c_raw "
|
27
|
+
static
|
28
|
+
VALUE
|
29
|
+
factorial_c_raw(int argc, VALUE *argv, VALUE self) {
|
30
|
+
int i=FIX2INT(argv[0]), result=1;
|
31
|
+
while (i >= 2) { result *= i--; }
|
32
|
+
return INT2NUM(result);
|
33
|
+
}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# breakeven for build run vs native doing 5 factorial:
|
38
|
+
# on a PIII/750 running FreeBSD: about 5000
|
39
|
+
# on a PPC/G4/800 running Mac OSX 10.2: always faster
|
40
|
+
|
41
|
+
require 'benchmark'
|
42
|
+
puts "RubyInline #{Inline::VERSION}" if $DEBUG
|
43
|
+
|
44
|
+
MyTest.send(:alias_method, :factorial_alias, :factorial_c_raw)
|
45
|
+
|
46
|
+
t = MyTest.new()
|
47
|
+
max = (ARGV.shift || 1_000_000).to_i
|
48
|
+
n = (ARGV.shift || 5).to_i
|
49
|
+
m = t.factorial(n)
|
50
|
+
|
51
|
+
def validate(n, m)
|
52
|
+
if n != m then raise "#{n} != #{m}"; end
|
53
|
+
end
|
54
|
+
|
55
|
+
puts "# of iterations = #{max}, n = #{n}"
|
56
|
+
Benchmark::bm(20) do |x|
|
57
|
+
x.report("null_time") do
|
58
|
+
for i in 0..max do
|
59
|
+
# do nothing
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
x.report("c") do
|
64
|
+
for i in 0..max do
|
65
|
+
validate(t.factorial_c(n), m)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
x.report("c-raw") do
|
70
|
+
for i in 0..max do
|
71
|
+
validate(t.factorial_c_raw(n), m)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
x.report("c-alias") do
|
76
|
+
for i in 0..max do
|
77
|
+
validate(t.factorial_alias(n), m)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
x.report("pure ruby") do
|
82
|
+
for i in 0..max do
|
83
|
+
validate(t.factorial(n), m)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/example2.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/local/bin/ruby17 -w
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
rescue LoadError
|
6
|
+
$: << 'lib'
|
7
|
+
end
|
8
|
+
require 'inline'
|
9
|
+
|
10
|
+
class MyTest
|
11
|
+
|
12
|
+
inline do |builder|
|
13
|
+
|
14
|
+
builder.add_compile_flags %q(-x c++)
|
15
|
+
builder.add_link_flags %q(-lstdc++)
|
16
|
+
|
17
|
+
builder.include "<iostream>"
|
18
|
+
|
19
|
+
builder.c "
|
20
|
+
static
|
21
|
+
void
|
22
|
+
hello(int i) {
|
23
|
+
while (i-- > 0) {
|
24
|
+
std::cout << \"hello\" << std::endl;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
t = MyTest.new()
|
32
|
+
|
33
|
+
t.hello(3)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
##
|
2
|
+
# Inline::Mapping - mapping method names from impl to test.
|
3
|
+
#
|
4
|
+
# Method names are mapped bidirectionally in the following way:
|
5
|
+
#
|
6
|
+
# method test_method
|
7
|
+
# method? test_method_eh (too much exposure to Canadians :)
|
8
|
+
# method! test_method_bang
|
9
|
+
# method= test_method_equals
|
10
|
+
# [] test_index
|
11
|
+
# * test_times
|
12
|
+
# == test_equals2
|
13
|
+
# === test_equals3
|
14
|
+
#
|
15
|
+
# Further, any of the test methods should be able to have arbitrary
|
16
|
+
# extensions put on the name to distinguish edge cases:
|
17
|
+
#
|
18
|
+
# method test_method
|
19
|
+
# method test_method_simple
|
20
|
+
# method test_method_no_network
|
21
|
+
#
|
22
|
+
# To allow for unmapped test methods (ie, non-unit tests), name them:
|
23
|
+
#
|
24
|
+
# test_integration_.*
|
25
|
+
|
26
|
+
module Inline
|
27
|
+
module Mapping
|
28
|
+
|
29
|
+
@@orig_method_map = {
|
30
|
+
'!' => 'bang',
|
31
|
+
'%' => 'percent',
|
32
|
+
'&' => 'and',
|
33
|
+
'*' => 'times',
|
34
|
+
'**' => 'times2',
|
35
|
+
'+' => 'plus',
|
36
|
+
'-' => 'minus',
|
37
|
+
'/' => 'div',
|
38
|
+
'<' => 'lt',
|
39
|
+
'<=' => 'lte',
|
40
|
+
'<=>' => 'spaceship',
|
41
|
+
"<\<" => 'lt2',
|
42
|
+
'==' => 'equals2',
|
43
|
+
'===' => 'equals3',
|
44
|
+
'=~' => 'equalstilde',
|
45
|
+
'>' => 'gt',
|
46
|
+
'>=' => 'ge',
|
47
|
+
'>>' => 'gt2',
|
48
|
+
'+@' => 'unary_plus',
|
49
|
+
'-@' => 'unary_minus',
|
50
|
+
'[]' => 'index',
|
51
|
+
'[]=' => 'index_equals',
|
52
|
+
'^' => 'carat',
|
53
|
+
'|' => 'or',
|
54
|
+
'~' => 'tilde',
|
55
|
+
}
|
56
|
+
|
57
|
+
@@method_map = @@orig_method_map.merge(@@orig_method_map.invert)
|
58
|
+
|
59
|
+
@@mapped_re = @@orig_method_map.values.sort_by { |k| k.length }.map {|s|
|
60
|
+
Regexp.escape(s)
|
61
|
+
}.reverse.join("|")
|
62
|
+
|
63
|
+
def munge name
|
64
|
+
name = name.to_s.dup
|
65
|
+
|
66
|
+
is_cls_method = name.sub!(/^self\./, '')
|
67
|
+
|
68
|
+
name = @@method_map[name] if @@method_map.has_key? name
|
69
|
+
name = name.sub(/=$/, '_equals')
|
70
|
+
name = name.sub(/\?$/, '_eh')
|
71
|
+
name = name.sub(/\!$/, '_bang')
|
72
|
+
|
73
|
+
name = yield name if block_given?
|
74
|
+
|
75
|
+
name = "class_" + name if is_cls_method
|
76
|
+
|
77
|
+
name
|
78
|
+
end
|
79
|
+
|
80
|
+
# Generates a test method name from a normal method,
|
81
|
+
# taking into account names composed of metacharacters
|
82
|
+
# (used for arithmetic, etc
|
83
|
+
def normal_to_test name
|
84
|
+
"test_#{munge name}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def unmunge name
|
88
|
+
name = name.to_s.dup
|
89
|
+
|
90
|
+
is_cls_method = name.sub!(/^class_/, '')
|
91
|
+
|
92
|
+
name = name.sub(/_equals(_.*)?$/, '=') unless name =~ /index/
|
93
|
+
name = name.sub(/_bang(_.*)?$/, '!')
|
94
|
+
name = name.sub(/_eh(_.*)?$/, '?')
|
95
|
+
name = name.sub(/^(#{@@mapped_re})(_.*)?$/) {$1}
|
96
|
+
name = yield name if block_given?
|
97
|
+
name = @@method_map[name] if @@method_map.has_key? name
|
98
|
+
name = 'self.' + name if is_cls_method
|
99
|
+
|
100
|
+
name
|
101
|
+
end
|
102
|
+
|
103
|
+
# Converts a method name beginning with test to its
|
104
|
+
# corresponding normal method name, taking into account
|
105
|
+
# symbolic names which may have been anglicised by
|
106
|
+
# #normal_to_test().
|
107
|
+
def test_to_normal(name, klassname=nil)
|
108
|
+
unmunge(name.to_s.sub(/^test_/, '')) do |n|
|
109
|
+
if defined? @inherited_methods then
|
110
|
+
known_methods = (@inherited_methods[klassname] || {}).keys.sort.reverse
|
111
|
+
known_methods_re = known_methods.map {|s| Regexp.escape(s) }.join("|")
|
112
|
+
n = n.sub(/^(#{known_methods_re})(_.*)?$/) { $1 } unless
|
113
|
+
known_methods_re.empty?
|
114
|
+
n
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|