Other Systems | 183
def factorial(n)
result = 1
n.downto(2) { |x| result *= x }
result
end
# Reimplemented in C (compiled on the fly)
inline do |builder|
builder.c <<-EOINLINE
long factorial_c(int max) {
int i = max,
result = 1;
while (i >= 2) { result *= i--; }
return result;
}
EOINLINE
end
end
We can then set up a benchmark to compare the two implementations:
t = Test.new
Benchmark.bmbm do |b|
b.report("Ruby factorial") do
200_000.times { t.factorial(20) }
end
b.report("C factorial") do
200_000.times { t.factorial_c(20) }
end
end
On my machine, the C implementation is extremely fast—more than 25 times the
speed of the standard Ruby implementation!
user system total real
Ruby factorial 2.760000 0.010000 2.770000 ( 2.753621)
C factorial 0.110000 0.000000 0.110000 ( 0.104440)
The best part of RubyInline is that it keeps your code clean. Ruby and C code
addressing the same area can be intermingled, rather than being spread across multi-
ple files. And RubyInline handles the type conversion for you—you can deal with
ints,longs, andchar *s, and they will automatically be converted to and from Ruby
types.
ActionMailer
Email delivery can be a difficult and aggravating aspect of a deployed application.
The SMT Pprotocol was not designed to withstand the types of attacks that are being
directed at the mail system today, and so delivering mail can be a more complicated
process than it may seem.