Changeset 1026

Show
Ignore:
Timestamp:
11/19/07 01:16:54 (10 months ago)
Author:
has.s..@gmail.com
Message:

Adds haml performance benchmarks. Also adds options as per commit [1025] for the merb benchmark app.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • apps/rails_benchmark/script/benchmark

    r1019 r1026  
    11#!/usr/bin/env ruby 
    22require 'open3' 
     3require 'optparse' 
    34$stdout.sync = true 
     5@options = {} 
     6@scenarios = {} 
     7@err = STDERR.dup 
     8 
     9opts = OptionParser.new do |opts| 
     10   
     11  opts.banner = "Usage: ./script/benchmark [cts] argument" 
     12  opts.define_head "Benchmark for the Rails web framework" 
     13  opts.separator '*'*80 
     14   
     15  opts.on("-c", "--concurrency NUMBER", "This flag is for setting the concurrency during the test.") do |config| 
     16    @options[:concurrency] = config.to_i 
     17  end 
     18   
     19  opts.on("-t", "--times NUMBER", "This flag sets the number of iterations to perform during the test.") do |config| 
     20    @options[:times] = config.to_i 
     21  end 
     22   
     23  opts.on("-s", "--scenarios LIST,OF,SENARIOS", "This flag allows you to select which scenario you want to run.  Multiple scenarios can be run by supplying a comma seperated list.") do |config| 
     24    @options[:scenarios] = config.split(",") 
     25  end 
     26   
     27  opts.on("-l", "--[no-]list", "Lists all available scenarios") do |config| 
     28    @options[:list] = config 
     29  end 
     30end 
     31 
     32@options = opts.getopts 
     33 
     34def call_ab(msg, url) 
     35  print "  ** #{msg} " 
     36  Open3.popen3("ab -n#{TIMES} -c#{CNCRC} http://127.0.0.1:4000/#{url}") do |strin, out, err| 
     37    while true 
     38      error, output = err.gets, out.gets 
     39      next unless (error || output) 
     40      print "." if  error =~ /Completed/ 
     41      STDOUT.flush 
     42      output = out.gets 
     43      if (output =~ /Requests per second/) 
     44        puts "\n     " + output 
     45        break 
     46      end 
     47      sleep 0.05 
     48    end 
     49  end 
     50end 
     51 
     52def get_rps(str) 
     53  GC.start 
     54  sleep 1 
     55  "     " + str.find {|x| x =~ /Requests per second/ }     
     56end 
     57 
     58def put_header_message(message) 
     59  spacer = "-" * (39 - message.length / 2) 
     60  @err.puts "#{spacer} #{message} #{spacer}" 
     61end 
     62 
     63def add_scenario(name, title, &block) 
     64  @scenarios[name] = [title, block] 
     65end 
     66 
     67def run_scenarios 
     68   
     69  @err.puts "* Benchmarks (These may take a while)" 
     70  @err.puts "* Requests per benchmark: #{TIMES}" 
     71  @err.puts "* Concurrency:            #{CNCRC}" 
     72 
     73  @err.puts 
     74   
     75  list = @options["scenarios"] || ["all"] 
     76  if list.include?("all") 
     77    run_list = @scenarios.map{|k,v| v } 
     78  else 
     79    run_list = @scenarios.keys.sort.map{|k| @scenarios[k] if list.include?(k)} 
     80  end 
     81   
     82  run_list = run_list.compact 
     83  @err.puts "Available Scenarios #{[@scenarios.keys, "all"].flatten.sort.join(",")}" and exit if run_list.empty? 
     84   
     85  run_list.each do |scn| 
     86    put_header_message(scn.first) 
     87    scn.last.call 
     88  end 
     89 
     90end 
     91 
     92 
     93# =========================  ADD SCENARIOS HERE =============================================== 
     94add_scenario("static", "Static Files") do 
     95  call_ab("Serve Static File", "hello.txt") 
     96end 
     97 
     98add_scenario("erb", "Templates and Partials - (ERB)") do  
     99  call_ab("Render a string", "perf/string") 
     100  call_ab("Render a simple template", "perf/simple_template") 
     101   
     102  [1,10,100].each do |number| 
     103    call_ab("Render #{number} simple partial#{'s' if number > 1}", "perf/partials/#{number}") 
     104  end 
     105   
     106  [1,10,100].each do |number| 
     107    call_ab("Render #{number} nested partial#{'s' if number > 1}", "perf/complex_partials/#{number}") 
     108  end 
     109end 
     110 
     111add_scenario("haml", "Templates and Partials - (HAML)") do 
     112  call_ab("Render a string", "haml_perf/string") 
     113  call_ab("Render a simple template", "haml_perf/simple_template") 
     114 
     115  [1,10,100].each do |number| 
     116    call_ab("Render #{number} simple partial#{'s' if number > 1}", "haml_perf/partials/#{number}") 
     117  end 
     118 
     119  [1,10,100].each do |number| 
     120    call_ab("Render #{number} nested partial#{'s' if number > 1}", "haml_perf/complex_partials/#{number}") 
     121  end 
     122end 
     123 
     124add_scenario("url", "URL Generation") do 
     125  [1,10,100].each do |number| 
     126    call_ab("Render #{number} simple named url#{'s' if number > 1}", "url_perf/simple_named_url_generation/#{number}") 
     127  end 
     128 
     129  [1,10,100].each do |number| 
     130    call_ab("Render #{number} top level nested named url#{'s' if number > 1}", "url_perf/top_level_nested_named_url_generation/#{number}") 
     131  end 
     132 
     133  [1,10,100].each do |number| 
     134    call_ab("Render #{number} second level nested named url#{'s' if number > 1}", "url_perf/second_level_nested_named_url_generation/#{number}") 
     135  end 
     136end 
     137 
     138 
     139  # =========================  FINISH SCENARIOS HERE =============================================== 
     140 
     141 
     142if @options['list'] 
     143  out = <<-EOD 
     144   
     145  Available Scenarios: #{@scenarios.keys.sort.join(", ")} 
     146 
     147  EOD 
     148  @err.puts out  
     149  exit 
     150end 
     151 
    4152begin 
    5   err = STDERR.dup 
     153   
    6154 
    7155  if File.exists?("#{File.dirname(__FILE__)}/../log/mongrel.pid") 
     
    9157  end 
    10158 
    11   err.puts "* Starting Rails" 
     159  @err.puts "* Starting Rails" 
    12160  ENV["EVENT"] = "1" 
    13161  `mongrel_rails start -d -p 4000 -e production` 
     
    20168  memsize = (ps.split("\n")[1].split[5].to_f / 10.24).round / 100.0 
    21169 
    22   err.puts "* Memory size before benchmarking: #{memsize}MB" 
     170  @err.puts "* Memory size before benchmarking: #{memsize}MB" 
    23171 
    24   TIMES = ARGV.find{|x| x =~ /^-t/ }[2..-1].to_i rescue 1000 
    25   CNCRC = ARGV.find{|x| x =~ /^-c/ }[2..-1].to_i rescue 5 
     172  TIMES = @options["times"] || 1000 
     173  CNCRC = @options["concurrency"]|| 5  
    26174 
    27   def call_ab(msg, url) 
    28     print "  ** #{msg} " 
    29     Open3.popen3("ab -n#{TIMES} -c#{CNCRC} http://127.0.0.1:4000/#{url}") do |strin, out, err| 
    30       while true 
    31         error, output = err.gets, out.gets 
    32         next unless (error || output) 
    33         print "." if  error =~ /Completed/ 
    34         STDOUT.flush 
    35         output = out.gets 
    36         if (output =~ /Requests per second/) 
    37           puts "\n     " + output 
    38           break 
    39         end 
    40         sleep 0.05 
    41       end 
    42     end 
    43   end 
    44  
    45   def get_rps(str) 
    46     GC.start 
    47     sleep 1 
    48     "     " + str.find {|x| x =~ /Requests per second/ }     
    49   end 
    50  
    51   def put_header_message(message) 
    52     spacer = "-" * (39 - message.length / 2) 
    53     puts "#{spacer} #{message} #{spacer}" 
    54   end 
    55  
    56   err.puts "* Benchmarks (These may take a while)" 
    57   err.puts "* Requests per benchmark: #{TIMES}" 
    58   err.puts "* Concurrency:            #{CNCRC}" 
    59  
    60   err.puts 
    61    
    62   put_header_message("Static files") 
    63   call_ab("Serve Static File", "hello.txt") 
    64  
    65   put_header_message("Templates and Partials")  
    66   call_ab("Render a string", "perf/string") 
    67   call_ab("Render a simple template", "perf/simple_template") 
    68    
    69   [1,10,100].each do |number| 
    70     call_ab("Render #{number} simple partial#{'s' if number > 1}", "perf/partials/#{number}") 
    71   end 
    72    
    73   [1,10,100].each do |number| 
    74     call_ab("Render #{number} nested partial#{'s' if number > 1}", "perf/complex_partials/#{number}") 
    75   end 
    76    
    77   put_header_message("URL Generation") 
    78    
    79   [1,10,100].each do |number| 
    80     call_ab("Render #{number} simple named url#{'s' if number > 1}", "url_perf/simple_named_url_generation/#{number}") 
    81   end 
    82    
    83   [1,10,100].each do |number| 
    84     call_ab("Render #{number} top level nested named url#{'s' if number > 1}", "url_perf/top_level_nested_named_url_generation/#{number}") 
    85   end 
    86    
    87   [1,10,100].each do |number| 
    88     call_ab("Render #{number} second level nested named url#{'s' if number > 1}", "url_perf/second_level_nested_named_url_generation/#{number}") 
    89   end 
     175  run_scenarios 
    90176 
    91177  ps = `ps aux #{pid}` 
    92178  memsize = (ps.split("\n")[1].split[5].to_f / 10.24).round / 100.0 
    93179 
    94   err.puts  
    95   err.puts "* Memory size after benchmarking: #{memsize}MB" 
     180  @err.puts  
     181  @err.puts "* Memory size after benchmarking: #{memsize}MB" 
    96182ensure 
    97183  `mongrel_rails stop`