diff --git a/performance/benchmark.rb b/performance/benchmark.rb new file mode 100644 index 0000000..74301ee --- /dev/null +++ b/performance/benchmark.rb @@ -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 + diff --git a/performance/profile.rb b/performance/profile.rb new file mode 100644 index 0000000..61688c5 --- /dev/null +++ b/performance/profile.rb @@ -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 diff --git a/performance/shopify.rb b/performance/theme_runner.rb similarity index 72% rename from performance/shopify.rb rename to performance/theme_runner.rb index d4055a9..ffac20e 100644 --- a/performance/shopify.rb +++ b/performance/theme_runner.rb @@ -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 <