I’m a performance guy, I’ll admit it. I love performance tuning and comparing code to see why one thing is slower than another. I’ve recently taken a shine to the Clojure programming language as it seems to combine two good things: an incredibly fast and reliable VM and a functional language designed for concurrency. Here’s my first performance test: the ever-reliable fibonacci method. Please remember this is just a microbenchmark, take it with a grain of salt.
In Clojure:
(defn fib [n]
(if (<= n 1)
1
(+ (fib (- n 1)) (fib (- n 2)))
)
)
In Ruby:
def fib(n)
return 1 if n <= 1
fib(n-1) + fib(n-2)
end
The JVM is Server 1.6.0_07 64-bit. Let’s see how long each takes to calculate the 40th Fibonacci number:
C (gcc 4.0.1) 2.6 sec
Java 1.2 sec
Clojure 20080916 11.3 sec
Ruby 1.9pr1 44.3 sec
JRuby 1.1.5 118.1 sec
Ruby 1.8.6 195.6 sec
Clojure’s performance is really spectacular in this one microbenchmark compared to Ruby. There’s some language overhead but the native speed is so fast that performance is still better than the fastest Ruby VMs. Rich Hickey has done a great job with Clojure but make no mistake, this is still mostly a hobbyist language done by one person - he can’t afford to spend years building his own VM. Running native on the JVM has huge benefits in terms of performance.
Tags: Ruby · Software
Here’s an interesting talk from Reginald Braithwaite on Ruby code manipulation. I’m wondering if the difficulties he’s found in trying to build macro processing in Ruby is intrinstic in Ruby’s design. It seems like macros are a fringe feature in Ruby, but a core feature in Lispy languages due to language design. When code is data and data is code, macros become second nature.
InfoQ: Ruby.rewrite Ruby
Tags: Software
DataFabric 1.2 supports ActiveRecord 2.2 and its overhauled connection handling. Believe me, this is a good thing. The old connection handling code was awful; the new code is much nicer.
How It Works
data_fabric 1.0 supported dynamic connections by proxying the connection stored in the global static connection hash. This is thread-unsafe and therefore didn’t support ActiveRecord’s multithreaded mode (allow_concurrency = true).
data_fabric 1.2 supports ActiveRecord 2.0 and 2.1 through the exact same code as data_fabric 1.1 except refactored to load only when those two versions are detected. If ActiveRecord 2.2 or greater is detected, the new proxy code is used. The new proxy works on a per-class basis and overrides the four class methods which make up the public connection API on ActiveRecord::Base:
def data_fabric(options)
DataFabric.log { "Creating data_fabric proxy for class #{name}" }
@proxy = DataFabric::ConnectionProxy.new(self, options)
class << self
def connection
@proxy
end
def connected?
@proxy.connected?
end
def remove_connection(klass)
DataFabric.log(Logger::ERROR) { "remove_connection not implemented by data_fabric" }
end
def connection_pool
raise "dynamic connection switching means you cannot get direct access to a pool"
end
end
end
This proxy is thread-safe in that its mutable state is stored in thread-local variables. Note the latter two methods aren’t implemented, for reasons you can see. remove_connection would be nice to implement but since we don’t use it at FiveRuns, I didn’t see any immediate need for it. I would happily accept patches for it.
Tags: Rails
November 27th, 2008 · 2 Comments
Here’s the video for my RubyConf 2008 talk, Patterns in Distributed Computing.
Tags: Software
A very good overview of consensus, the fundamental problem in distributed computing. My talk and politics project deal heavily in this stuff.
Consensus Protocols: Two-Phase Commit at Paper Trail
Tags: Software
I’ve pulled a few changes from Jeffrey Hardy at 37signals, and added a few of my own. Most of the fixes are for Ruby 1.9 compatibility. From the history:
- Get test suite working again (packagethief)
- Ruby 1.9 compatiblity fixes (packagethief, mperham)
- Consistently return server responses and check for errors (packagethief)
- Properly calculate CRC in Ruby 1.9 strings (mperham)
- Drop rspec in favor of test/unit, for 1.9 compat (mperham)
sudo gem install fiveruns-memcache-client -s http://gems.github.com
Please comment if you have any issues or questions.
UPDATE: And just as soon as I’m done with the announcement, I release 1.5.0.5.
Tags: Ruby
November 23rd, 2008 · 6 Comments
This blog is usually dry and technical. Let’s go off the beaten path and have a bit of fun with a caption contest. Meet Steve and his pet rat. What is he saying?

Tags: Software
I cleaned up the blog style as I thought the previous look and feel was a little busy. I hope you like the changes!
Tags: Personal
Justin Balthrop at Geni was nice enough to donate a few fixes to data_fabric. The major issue was that when the connection changed, the plugin established a brand new connection. With his changes, data_fabric will now cache the connection and reuse it. This can lead to a noticeable performance increase if your code was switching connections frequently.
The logging code was also refactored to simplify it and fix a nil pointer I frequently ran into.
The changes pass all the existing tests but they are significant. Please test on your own and let me know if you have any issues.
sudo gem install data_fabric
Note: this release is not compatible with Rails 2.2. The next one will be.
Tags: Rails
November 13th, 2008 · 5 Comments
I tested tracknowledge with Rails 2.2 yesterday. The main problem was with plugins: two out of the six I use failed with the same issue when used with threadsafe!
The issue is that ActiveSupport’s autoloading is turned off once threadsafe! is executed because autoloading is inherently thread-unsafe. These plugins were not explicitly requiring their classes in init.rb but instead relying on autoloading like so:
config/environment.rb:
Rails::Initializer.run do |config|
config.threadsafe!
end
ExceptionNotifier.exception_recipients = %w(mikeATtracknowledge.org)
Yes, ExceptionNotifier was one of the broken plugins along with the GeoKit plugin. The fix is simple:
diff --git a/vendor/plugins/exception_notification/init.rb b/vendor/plugins/exception_notification/init.rb
index b39bd95..b1dd2d9 100644
--- a/vendor/plugins/exception_notification/init.rb
+++ b/vendor/plugins/exception_notification/init.rb
@@ -1 +1,4 @@
require "action_mailer"
+require 'exception_notifier'
+require 'exception_notifiable'
+require 'exception_notifier_helper'
If you maintain a Rails plugin, make sure you verify that all classes are loaded in init.rb or you could very well have problems too.
Tags: Rails