Ruby’s DBI or ActiveRecord

While creating a small CGI web application in Ruby the question came up about how much slower ActiveRecord is than DBI. Considering that ActiveRecord is initialized each time the CGI runs the performance hit could be significant.

So why not use Rails instead? The server that I am running the application on has limited resources. Rails is reported to need about 20 MB of memory and the node I have is already paging out memory to disk.

To emulate the webserver getting hit repeatedly with connections I created a connect_dbi.rb and and connect_ar.rb that insert the same row into a Tests database table. The ActiveRecord test also has the model file test.rb

The test was run using a PostGreSQL database on Ubuntu 5.10 with Ruby 1.8.4. The table was truncated between tests. I just wanted to get an idea of the performance difference between ActiveRecord and DBI. So this isn’t the strictest performance test but does provide an idea of the magnitude of difference.


The test was executed from the command line using “ruby -e” to call the connect_dbi.rb and connect_ar.rb files 100 times each. This creates a new database connection each time the script is executed. ActiveRecord generates a series of error messages about unavailable database adapters each time it is started so these messages were capatured in the activeError file. DBI doesn’t produce any errors but I wanted to keep the execution as similar as possible so there is also a dbiError file created.

connect_dbi.rb

#! /usr/bin/ruby -w
require 'rubygems'
require 'dbi'

dbh = DBI.connect('dbi:Pg:tmp_test:localhost','ruby_user','ruby_pass')

begin

dbh.transaction do |dbh|
dbh.prepare("INSERT INTO tests(rank, created_at, message) VALUES(?,?,?)") do |sth|
sth.execute(5, Time.now, 'abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ')
end
end

rescue DBI::ProgrammingError => exception
puts "Exception: #{exception.message}"
end

connect_ar.rb

#! /usr/bin/ruby -w

require 'rubygems'
require_gem 'activerecord'

ActiveRecord::Base.establish_connection(
:adapter  => "postgresql",
:host     => "localhost",
:username => "ruby_user",
:password => "ruby_pass",
:database => "tmp_test"
)

test = Test.new("rank" => 5, "created_at" => "#{Time.now}", "message" => 'abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ')
test.save

test.rb

class Test < ActiveRecord::Base

end

The GNU/Linux time command was used to obtain timings.

As the results show DBI appears to be about three times faster than using ActiveRecord. This is most likely because of the initialization ActiveRecord does each time the connection is established. Considering that the test is only using one table and one ActiveRecord model class this is a fairly significant difference.

~/projects/dbi_test $ time ruby -e '100.times { %x{./connect_ar.rb}}' 2> activeError

real    0m25.916s
user    0m21.575s
sys     0m2.807s

~/projects/dbi_test $ time ruby -e '100.times { %x{./connect_dbi.rb}}' 2> dbiError

real    0m8.154s
user    0m6.620s
sys     0m0.733s
All results are in seconds.  Each test was run ten times.

DBI Results

Mean Standard Deviation
Real 7.7133 0.9448
User 6.2027 0.8530
Sys 6.2027 0.2760

ActiveRecord Results

Mean Standard Deviation
Real 26.9003 1.8849
User 21.9256 1.4959
Sys 2.8038 0.4610
del.icio.us:Ruby's DBI or ActiveRecord digg:Ruby's DBI or ActiveRecord spurl:Ruby's DBI or ActiveRecord wists:Ruby's DBI or ActiveRecord simpy:Ruby's DBI or ActiveRecord newsvine:Ruby's DBI or ActiveRecord blinklist:Ruby's DBI or ActiveRecord furl:Ruby's DBI or ActiveRecord reddit:Ruby's DBI or ActiveRecord fark:Ruby's DBI or ActiveRecord blogmarks:Ruby's DBI or ActiveRecord Y!:Ruby's DBI or ActiveRecord smarking:Ruby's DBI or ActiveRecord magnolia:Ruby's DBI or ActiveRecord segnalo:Ruby's DBI or ActiveRecord gifttagging:Ruby's DBI or ActiveRecord

2 Responses to “Ruby’s DBI or ActiveRecord”

  1. kmeyer Says:

    I would like to see how much slower your ActiveRecord version is if you use fastcgi.

    http://wiki.rubygarden.org/Ruby/page/show/FCGIRubyPerformance

Leave a Reply