improved benchmark suite

This commit is contained in:
Tobias Lütke 2011-01-28 21:14:38 -05:00
parent f7ff9c81d3
commit 9c49b8bbb2
3 changed files with 57 additions and 38 deletions

10
performance/benchmark.rb Normal file
View File

@ -0,0 +1,10 @@
require 'rubygems'
require 'benchmark'
require File.dirname(__FILE__) + '/theme_runner'
profiler = ThemeRunner.new
Benchmark.bmbm do |x|
x.report("parse & run:") { 10.times { profiler.run(false) } }
end

19
performance/profile.rb Normal file
View File

@ -0,0 +1,19 @@
require 'rubygems'
require 'ruby-prof' rescue fail("install ruby-prof extension/gem")
require File.dirname(__FILE__) + '/theme_runner'
profiler = ThemeRunner.new
puts 'Running profiler...'
results = profiler.run(true)
puts 'Success'
puts
[RubyProf::FlatPrinter, RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter, RubyProf::CallTreePrinter].each do |klass|
filename = (ENV['TMP'] || '/tmp') + (klass.name.include?('Html') ? "/liquid.#{klass.name.downcase}.html" : "/liquid.#{klass.name.downcase}.txt")
filename.gsub!(/:+/, '_')
File.open(filename, "w+") { |fp| klass.new(results).print(fp) }
$stderr.puts "wrote #{klass.name} output to #{filename}"
end

View File

@ -13,55 +13,62 @@ require 'digest/md5'
require File.dirname(__FILE__) + '/shopify/liquid'
require File.dirname(__FILE__) + '/shopify/database.rb'
require "ruby-prof" rescue fail("install ruby-prof extension/gem")
class ThemeRunner
class ThemeProfiler
# Load all templates into memory, do this now so that
# we don't profile IO.
def initialize
@tests = Dir[File.dirname(__FILE__) + '/tests/**/*.liquid'].collect do |test|
next if File.basename(test) == 'theme.liquid'
theme_path = File.dirname(test) + '/theme.liquid'
[File.read(test), (File.file?(theme_path) ? File.read(theme_path) : nil), test]
end.compact
end
def profile
RubyProf.measure_mode = RubyProf::WALL_TIME
def run(profile = false)
RubyProf.measure_mode = RubyProf::WALL_TIME if profile
# Dup assigns because will make some changes to them
assigns = Database.tables.dup
@tests.each do |liquid, layout, template_name|
# Compute page_tempalte outside of profiler run, uninteresting to profiler
html = nil
page_template = File.basename(template_name, File.extname(template_name))
# Profile compiling and rendering both
RubyProf.resume { html = compile_and_render(liquid, layout, assigns, page_template) }
if profile
RubyProf.resume do
html = compile_and_render(liquid, layout, assigns, page_template)
end
else
html = compile_and_render(liquid, layout, assigns, page_template)
end
# return the result and the MD5 of the content, this can be used to detect regressions between liquid version
$stdout.puts "* rendered template %s, content: %s" % [template_name, Digest::MD5.hexdigest(html)]
$stdout.puts "* rendered template %s, content: %s" % [template_name, Digest::MD5.hexdigest(html)] if profile
# Uncomment to dump html files to /tmp so that you can inspect for errors
# File.open("/tmp/#{File.basename(template_name)}.html", "w+") { |fp| fp <<html}
end
RubyProf.stop
RubyProf.stop if profile
end
def compile_and_render(template, layout, assigns, page_template)
tmpl = Liquid::Template.new
tmpl.assigns['page_title'] = 'Page title'
tmpl.assigns['template'] = page_template
content_for_layout = tmpl.parse(template).render(assigns)
if layout
assigns['content_for_layout'] = content_for_layout
tmpl.parse(layout).render(assigns)
@ -72,21 +79,4 @@ class ThemeProfiler
end
profiler = ThemeProfiler.new
puts 'Running profiler...'
results = profiler.profile
puts 'Success'
puts
[RubyProf::FlatPrinter, RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter, RubyProf::CallTreePrinter].each do |klass|
filename = (ENV['TMP'] || '/tmp') + (klass.name.include?('Html') ? "/liquid.#{klass.name.downcase}.html" : "/liquid.#{klass.name.downcase}.txt")
filename.gsub!(/:+/, '_')
File.open(filename, "w+") { |fp| klass.new(results).print(fp) }
$stderr.puts "wrote #{klass.name} output to #{filename}"
end