Skip to content

Benchwarmer

2010/07/11

While trying to fix some performance problems on an application I’m working on, there were a couple of methods to sum values which were very similar in implementation. ┬áIn order to determine whether the new implementation I had in mind was faster, I used the Benchmark module included as part of the Ruby Standard Library.

Since FactoryGirl is being used for testing in this one, it made sense to use the existing factories to set up the infrastructure necessary to run the benchmarks, and it really made the whole process a snap!

Here’s a generic example of the class hierarchy for the code:

class Container
has_many :contained_objects
end

class ContainedObject
has_many :uploaded_files

attr_reader :uploaded_files_count
end

class UploadedFile
belongs_to :contained_object

attr_reader :count
end

And here’s the benchmarking script:


require 'factory_girl'
require 'benchmark'

# Require the factories used for testing
Dir.glob('spec/factories/*.rb').each { |f| require f }

# Create test data to run benchmarks on
@container = Factory(:container)
100.times { Factory(:contained_object, :container => @container) }

# Run benchmarks
Benchmark.bm do |b|
b.report("@contained_object#inject") do
100_000.times do
@container.contained_objects.inject(0) do |sum, contained_object|
sum += contained_object.uploaded_files_count
end
end
end

b.report("UploadedFiles#sum") do
100_000.times do
contained_objects = @container.contained_objects.map { |b| b.id }
UploadedFiles.sum(:count, :conditions => {:contained_object_id => contained_objects })
end
end
end

Here’s the result:

$ script/runner container_count_benchmark.rb
./script/../config/../vendor/rails/railties/lib/rails/gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is deprecated and will be removed on or after August 2010. Use #requirement
user system total real
@contained_object#inject 4683.010000 159.130000 4842.140000 (4987.951406)
UploadedFiles#sum 239.690000 1.980000 241.670000 (243.680010)

Looks like the clear winner is the class method, sum, by a total of about 4744.271396 seconds (that’s 80 minutes) over 100_000 iterations. This is one set of methods that just became a whole lot more performant.

Benchmarking is easy, and can be a great way to find bottlenecks in your code, or just determine which implementation of a given chunk of code is the fastest, so you can keep your applications running smooth and your clients happy!

Advertisements
Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: