DevEX - reference for building teams, processes, and platforms
Cより速いRubyプログラム
1. RubyKaigi 2007 Session
C Ruby
An Example of Ruby Program Faster Than C
makoto kuwata
http://www.kuwata-lab.com
copyright(c) 2007 kuwata-lab.com all rights reserved.
8. Point
≠
Language Speed ≠ Application Speed
copyright(c) 2007 kuwata-lab.com all rights reserved.
9. Overview
‣ :
‣ : C Ruby
‣ : eRuby
‣ : C
≦ Ruby
≪≪≪≪≪ C
copyright(c) 2007 kuwata-lab.com all rights reserved.
10. Conclusion
‣
•
‣
•
copyright(c) 2007 kuwata-lab.com all rights reserved.
11. eRuby
Introduction to eRuby
copyright(c) 2007 kuwata-lab.com all rights reserved.
12. eRuby
What is eRuby?
‣ eRuby (Embedded Ruby) …
Ruby ( )
‣ eRuby …
Ruby
Ruby
• eruby … C
• ERB … pure Ruby Ruby1.8
copyright(c) 2007 kuwata-lab.com all rights reserved.
13. Example
<table>
<tbody>
<% for item in list %>
<tr>
<td><%= item %></td>
</tr>
<% end %>
</tbody> <% ... ... %>
<table> <%= ... ... %>
copyright(c) 2007 kuwata-lab.com all rights reserved.
14. C eruby
Ruby Script Translated by eruby
print "<table>n"
print " <tbody>n"
for item in list ; print "n"
print " <tr>n"
print " <td>"; print(( item )); print "</td>n"
print " </tr>n"
end ; print "n"
print " </tbody>n" print
print "<table>n" 1
copyright(c) 2007 kuwata-lab.com all rights reserved.
15. ERB
Ruby Script Translated by ERB
_erbout = ""; _erbout.concat "<table>n"
_erbout.concat " <tbody>n"
for item in list ; _erbout.concat "n"
_erbout.concat " <tr>n"
_erbout.concat " <td>"; _erbout.concat(( item ).to_s);
_erbout.concat "</td>n"
_erbout.concat " </tr>n"
end ; _erbout.concat "n"
_erbout.concat " </tbody>n"
_erbout.concat "<table>n"
_erbout 1
copyright(c) 2007 kuwata-lab.com all rights reserved.
16. Output Example
<table>
<tbody>
<tr>
<td>AAA</td>
</tr>
<tr>
<td>BBB</td>
</tr>
<tr>
<td>CCC</td>
</tr>
</tbody> :
<table>
copyright(c) 2007 kuwata-lab.com all rights reserved.
17. Benchmark Environment
1: <html>
‣ 400 ..... : 53
10,000 53: <table>
54: <% for item in list %>
55: <tr>
‣ 10 56: <td><%= item['symbol'] %></td>
57: <td><%= item['name'] %></td>
‣ MacOS X 10.4 Tiger .....
79: </tr> : 17
(CoreDuo 1.83GHz) x20
80: <% end %>
‣ Ruby 1.8.6, eruby 1.0.5 81: </table>
..... :5
85: </html>
copyright(c) 2007 kuwata-lab.com all rights reserved.
20. #1:
#1: First Implementation
### Program
input.each_line do |line|
line.scan(/(.*?)(<%=?|%>)/) do
case $2
when '<%' ; ... 1
when '<%=' ; ...
when '%>' ; ...
...
end
end
...
http://www.kuwata-lab.com/presen/erubybench-1.1.zip
copyright(c) 2007 kuwata-lab.com all rights reserved.
21. #1: (2)
#1: First Implementation (2)
Ruby
### Translated
_buf = ""; _buf << "<html>n";
_buf << "<body>n" 1
_buf << " <table>n"
for item in list ; _buf << "n";
_buf << " <tr>n"
_buf << " <td>"; _buf << (item['name']).to_s;
_buf << "</td>n";
_buf << " </tr>n";
end ; _buf << "n";
...
copyright(c) 2007 kuwata-lab.com all rights reserved.
22. #1:
#1: Benchmark Result
100
75
50
25
0
C eruby ERB MyEruby1
copyright(c) 2007 kuwata-lab.com all rights reserved.
23. #2:
#2: Never Split Into Lines
copyright(c) 2007 kuwata-lab.com all rights reserved.
24. #2:
#2: Never Split into Lines
## Before
input.each_line do |line|
line.scan(/(.*?)(<%=?|%>)/).each do
...
end
end
## After
input.scan(/(.*?)(<%=?|%>)/m).each do
...
end
copyright(c) 2007 kuwata-lab.com all rights reserved.
25. #2: (2)
#2: Never Split into Lines (2)
Ruby
## Before
_buf << "<html>n"
_buf << " <body>n"
_buf << " <h1>title</h1>n"
## After
_buf << '<html>
<body>
<h1>title</h1>
';
copyright(c) 2007 kuwata-lab.com all rights reserved.
26. #2:
#2: Benchmark Result
100
75
50
25
0
C eruby ERB MyEruby1 MyEruby2
copyright(c) 2007 kuwata-lab.com all rights reserved.
27. #2:
#2: Benchmark Result
20
15
10
5
0
C eruby MyEruby2
copyright(c) 2007 kuwata-lab.com all rights reserved.
28. #3:
#3: Replace Parsing with Pattern Matching
copyright(c) 2007 kuwata-lab.com all rights reserved.
29. #3:
#3: Replace Parsing with Pattern Matching
## Before
input.scan(/(.*?)(<%=?|%>)/m) do
case $2
when '<%=' ; kind = :expr
when '<%' ; kind = :stmt
when '%>' ; kind = :text
...
## After
input.scan(/(.*?)<%(=?)(.*?)%>/m) do
text, equal, code = $1, $2, $3
s << _convert_str(text, :text)
s << _convert_str(code, equal=='=' ? :expr : :stmt)
...
copyright(c) 2007 kuwata-lab.com all rights reserved.
30. #3:
#3: Benchmark Result
20
15
10
5
0
C eruby MyEruby2 MyEruby3
copyright(c) 2007 kuwata-lab.com all rights reserved.
31. #4:
#4: Tune Up Regular Expressions
copyright(c) 2007 kuwata-lab.com all rights reserved.
32. #4:
#4: Tune Up Regular Expressions
## Before
input.scan(/(.*?)<%(=)?(.*?)%>/m) do
text, equal, code = $1, $2, $3
...
## After
pos = 0
input.scan(/<%(=)?(.*?)%>/m) do
equal, code = $1, $2
match = Regexp.last_match
len = match.begin(0) - pos
text = eruby_str[pos, len]
pos = match.end(0)
...
copyright(c) 2007 kuwata-lab.com all rights reserved.
33. #4:
#4: Benchmark Result
20
15
10
5
0
C eruby MyEruby2 MyEruby3 MyEruby4
copyright(c) 2007 kuwata-lab.com all rights reserved.
34. #5:
#5: Inline Expansion of Method Call
copyright(c) 2007 kuwata-lab.com all rights reserved.
35. #5:
#5: Inline Expansion of Method Call
### Before
...
s << _convert_str(code, :expr)
s << _convert_str(code, :stmt)
s << _convert_str(text, :text)
...
### After
...
s << "_buf << (#{code}).to_s; "
s << "#{code}; "
s << "_buf << '#{text.gsub(/[']/, '&')}'; "
...
copyright(c) 2007 kuwata-lab.com all rights reserved.
36. #5:
#5: Benchmark Result
20
15
10
5
0
C eruby MyEruby2 MyEruby3 MyEruby4 MyEruby5
copyright(c) 2007 kuwata-lab.com all rights reserved.
37. #6:
#6: Array Buffer
copyright(c) 2007 kuwata-lab.com all rights reserved.
38. #6:
#6: Array Buffer
Ruby
### Before
_buf = '';
_buf << '<td>'; _buf << (n).to_s; _buf << '</td>';
_buf
### After String#<<
_buf = []; 1 Array#push()
_buf.push('<td>', n, '</td>');
_buf.join
copyright(c) 2007 kuwata-lab.com all rights reserved.
39. #6:
#6: Benchmark Result
20
15
10
5
0
by
2
3
4
5
6
by
by
by
by
by
u
er
ru
ru
ru
ru
ru
yE
yE
yE
yE
yE
M
M
M
M
copyright(c) 2007 kuwata-lab.com all rights reserved. M
C
40. #7:
#7: Interpolation
copyright(c) 2007 kuwata-lab.com all rights reserved.
41. #7:
#7: Interpolation
Ruby
### Before
_buf << '<tr>
<td>'; _buf << (n).to_s; _buf << '</td>
</tr>';
String#<<
### After
_buf << %Q`<tr>
<td>#{n}</td>
"...str..."
</tr>`
%Q`...str...`
copyright(c) 2007 kuwata-lab.com all rights reserved.
42. #7:
#7: Benchmark Result
20
15
10
5
0
y
2
3
4
5
6
7
ub
by
by
by
by
by
by
er
ru
ru
ru
ru
ru
ru
yE
yE
yE
yE
yE
yE
M
M
M
M
M
copyright(c) 2007 kuwata-lab.com all rights reserved.
M
C
43. #8:
#7: File Caching
copyright(c) 2007 kuwata-lab.com all rights reserved.
44. #8:
#8: File Caching
## After
def convert_file(filename, cachename=nil)
cachename ||= filename + '.cache'
if or
prog = convert(File.read(filename))
(prog)
else
prog =
end
return prog Ruby
end
copyright(c) 2007 kuwata-lab.com all rights reserved.
45. #8:
#8: Benchmark Result
20
15
10
5
0
y
2
3
4
5
6
7
8
ub
by
by
by
by
by
by
by
er
ru
ru
ru
ru
ru
ru
ru
yE
yE
yE
yE
yE
yE
yE
M
M
M
M
M
M
M
copyright(c) 2007 kuwata-lab.com all rights reserved.
C
46. #9:
#7: Make Methods
copyright(c) 2007 kuwata-lab.com all rights reserved.
47. #9:
#9: Make Methods
### Before
prog = myeruby.convert_file(filename)
eval prog
### After Ruby
def define_method(body, args=[])
eval "def self.evaluate(#{args.join(',')}); #{body}; end"
end
prog = myeruby.convert_file(filename)
args = ['list']
myeruby.define_method(prog, args)
myeruby.evaluate()
copyright(c) 2007 kuwata-lab.com all rights reserved.
48. #9:
#9: Benchmark Result
20
15
10
5
0
y
2
3
4
5
6
7
8
9
ub
by
by
by
by
by
by
by
by
er
ru
ru
ru
ru
ru
ru
ru
ru
yE
yE
yE
yE
yE
yE
yE
yE
M
M
M
M
M
M
M
M
copyright(c) 2007 kuwata-lab.com all rights reserved.
C