Skip to content

Instantly share code, notes, and snippets.

@xaviershay
Created January 21, 2011 03:58
Show Gist options
  • Select an option

  • Save xaviershay/789211 to your computer and use it in GitHub Desktop.

Select an option

Save xaviershay/789211 to your computer and use it in GitHub Desktop.
# Trying to isolate some performance problems with collection rendering in a rails app.
#
# FAIL
#
# Need to move to a bare rails app next.
#
# Run this RUBY_PROF or BENCHMARK = 1 in your env.
require 'rubygems'
require 'dm-core'
require 'dm-migrations'
# Random gems not required for the test, but checking to see if they affect it
# require 'dm-constraints'
# require 'dm-types'
# require 'dm-aggregates'
# require 'dm-transactions'
# require 'dm-timestamps'
# require 'dm-adjust'
# require 'dm-validations'
require 'ruby-prof'
require 'benchmark'
def ruby_prof?
ENV['RUBY_PROF'] == '1'
end
def benchmark?
ENV['BENCHMARK'] == '1'
end
DataMapper::Logger.new($stdout, :debug) unless ruby_prof?
DataMapper.setup(:default, 'postgres://localhost/test') # createdb test
class Page
include DataMapper::Resource
property :id, Serial
property :title, String
has n, :containers
end
class Container
include DataMapper::Resource
property :id, Serial
property :number, Integer
belongs_to :page
has n, :slots
end
class Slot
include DataMapper::Resource
property :id, Serial
property :caption, String
belongs_to :container
belongs_to :content
end
class Content
include DataMapper::Resource
property :id, Serial
property :type, String
has n, :slots
has 1, :article, :child_key => [:id]
has 1, :image, :child_key => [:id]
end
class Article
include DataMapper::Resource
belongs_to :content, :key => true, :child_key => [:id]
property :body, Text, :lazy => false
end
class Image
include DataMapper::Resource
belongs_to :content, :key => true, :child_key => [:id]
property :source, String
end
DataMapper.finalize
DataMapper.auto_migrate!
page = Page.new(:title => 'Home Page', :containers => [
{:number => 0, :slots => [
{:caption => 'AA', :content => Content.create(:type => 'Article', :article => Article.new(:body => 'AA'))},
{:caption => 'BB', :content => Content.create({:type => 'Article', :article => {:body => 'BB'}})},
{:caption => 'CC', :content => Content.create({:type => 'Article', :article => {:body => 'CC'}})},
{:caption => 'DD', :content => Content.create({:type => 'Article', :article => {:body => 'DD'}})},
{:caption => 'EE', :content => Content.create({:type => 'Article', :article => {:body => 'EE'}})}]},
{:number => 1, :slots => [
{:caption => 'AA', :content => Content.create({:type => 'Article', :article => {:body => 'AA'}})},
{:caption => 'BB', :content => Content.create({:type => 'Article', :article => {:body => 'BB'}})},
{:caption => 'CC', :content => Content.create({:type => 'Article', :article => {:body => 'CC'}})},
{:caption => 'DD', :content => Content.create({:type => 'Article', :article => {:body => 'DD'}})},
{:caption => 'EE', :content => Content.create({:type => 'Article', :article => {:body => 'EE'}})}]}])
page.save || raise("Couldn't save fixture data")
repository do
RubyProf.start if ruby_prof?
buffer = ''
# Preload data - we are testing collections, not queries
page = Page.first
page.containers.map(&:slots).map(&:content).map(&:article)
puts "BENCHMARKING" unless ruby_prof?
test_code = lambda do
buffer = ''
page.containers.each do |container|
buffer += "Container #{container.number}\n"
container.slots.each do |slot|
buffer += " Slot #{slot.caption}: #{slot.content.article.body}\n"
end
end
end
if benchmark?
timing = Benchmark.measure do
100.times { test_code.call }
end
puts timing
else
test_code.call
end
if ruby_prof?
result = RubyProf.stop
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(STDOUT)
else
puts buffer
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment