Changeset 1025

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

Adds Haml performance benchmarks to the merb Benchmark app. Also includes updates to options.
ruby script/benchmark -h
to view available options.
Individual scenarios may now be selected for running.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • apps/benchmark/config/dependencies.rb

    r973 r1025  
    1919# use_orm :sequel 
    2020 
     21# Preload the HAML templating engine 
     22Merb::Template::Haml 
    2123 
    2224### This defines which test framework the generators will use 
  • apps/benchmark/script/benchmark

    r1020 r1025  
    11#!/usr/bin/env ruby 
    22require 'open3' 
    3 begin 
    4   err = STDERR.dup 
     3require 'optparse' 
    54 
    6   err.puts "* Starting Merb" 
    7   ENV["EVENT"] = "1" 
    8   `env EVENT=1 merb -d -e production` 
    9   pid = File.read("#{File.dirname(__FILE__)}/../log/merb.4000.pid") 
    10   sleep 5 
    11   ps = `ps aux #{pid}` 
    12   memsize = (ps.split("\n")[1].split[5].to_f / 10.24).round / 100.0 
     5@options = {} 
     6@scenarios = {} 
     7@err = STDERR.dup 
    138 
    14   err.puts "* Memory size before benchmarking: #{memsize}MB" 
     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", "Sets the concurrency number during the test.") do |config| 
     16    @options[:concurrency] = config.to_i 
     17  end 
     18   
     19  opts.on("-t", "--times NUMBER", "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,SCENARIOS", "Selects 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 
    1531 
    16   TIMES = ARGV.find{|x| x =~ /^-t/ }[2..-1].to_i rescue 1000 
    17   CNCRC = ARGV.find{|x| x =~ /^-c/ }[2..-1].to_i rescue 5 
    18    
     32@options = opts.getopts 
    1933 
    20   def call_ab(msg, url) 
    21     print "  ** #{msg} " 
    22     Open3.popen3("ab -n#{TIMES} -c#{CNCRC} http://127.0.0.1:4000/#{url}") do |strin, out, err| 
    23       while true 
    24         error, output = err.gets, out.gets 
    25         next unless (error || output) 
    26         print "." if  error =~ /Completed/ 
    27         STDOUT.flush 
    28         output = out.gets 
    29         if (output =~ /Requests per second/) 
    30           puts "\n     " + output 
    31           break 
    32         end 
    33         sleep 0.1 
     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 
    3446      end 
     47      sleep 0.1 
    3548    end 
    3649  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 
    3768   
    38   def put_header_message(message) 
    39     spacer = "-" * (39 - message.length / 2) 
    40     puts "#{spacer} #{message} #{spacer}" 
     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)} 
    4180  end 
    42  
    43   def get_rps(str) 
    44     GC.start 
    45     sleep 1 
    46     "     " + str.find {|x| x =~ /Requests per second/ }     
     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.compact.each do |scn| 
     86    put_header_message(scn.first) 
     87    scn.last.call 
    4788  end 
     89end 
    4890 
    4991 
    50   err.puts "* Benchmarks (These may take a while)" 
    51   err.puts "* Requests per benchmark: #{TIMES}" 
    52   err.puts "* Concurrency:            #{CNCRC}" 
     92# =========================  ADD SCENARIOS HERE =============================================== 
     93add_scenario("static", "Static Files") do 
     94  call_ab("Serve Static File", "hello.txt") 
     95end 
    5396 
    54   err.puts 
    55  
    56   sleep 1 
    57  
    58   put_header_message("Static files") 
    59   call_ab("Serve Static File", "hello.txt")  
     97add_scenario("erb", "Templates and Partials - (ERB)") do  
     98  call_ab("Render a string", "perf/string") 
    6099   
    61   put_header_message("Templates and Partials") 
    62   call_ab("Render a string", "perf/string") 
    63100  call_ab("Render a simple template", "perf/simple_template") 
    64101   
     
    70107    call_ab("Render #{number} nested partial#{'s' if number > 1}", "perf/complex_partials/#{number}") 
    71108  end 
     109end 
     110 
     111add_scenario("haml", "Templates and Partials - (HAML)") do 
     112  call_ab("Render a string", "haml_perf/string") 
    72113   
    73   put_header_message("URL Generation") 
     114  call_ab("Render a simple template", "haml_perf/simple_template") 
     115 
     116  [1,10,100].each do |number| 
     117    call_ab("Render #{number} simple partial#{'s' if number > 1}", "haml_perf/partials/#{number}") 
     118  end 
     119 
     120  [1,10,100].each do |number| 
     121    call_ab("Render #{number} nested partial#{'s' if number > 1}", "haml_perf/complex_partials/#{number}") 
     122  end 
     123end 
     124 
     125add_scenario("url", "URL Generation") do 
    74126  [1,10,100].each do |number| 
    75127    call_ab("Render #{number} simple named url#{'s' if number > 1}", "url_perf/simple_named_url_generation/#{number}") 
    76128  end 
    77    
     129 
    78130  [1,10,100].each do |number| 
    79131    call_ab("Render #{number} top level nested named url#{'s' if number > 1}", "url_perf/top_level_nested_named_url_generation/#{number}") 
    80132  end 
    81    
     133 
    82134  [1,10,100].each do |number| 
    83135    call_ab("Render #{number} second level nested named url#{'s' if number > 1}", "url_perf/second_level_nested_named_url_generation/#{number}") 
    84136  end 
     137end 
     138 
     139 
     140  # =========================  FINISH SCENARIOS HERE =============================================== 
     141   
     142   
     143if @options['list'] 
     144  out = <<-EOD 
     145   
     146  Available Scenarios: #{@scenarios.keys.sort.join(", ")} 
     147       
     148  EOD 
     149  @err.puts out  
     150  exit 
     151end 
     152 
     153begin 
     154   
     155  @err.puts "* Starting Merb" 
     156  ENV["EVENT"] = "1" 
     157  `env EVENT=1 merb -d -e production` 
     158  pid = File.read("#{File.dirname(__FILE__)}/../log/merb.4000.pid") 
     159  sleep 5 
     160  ps = `ps aux #{pid}` 
     161  memsize = (ps.split("\n")[1].split[5].to_f / 10.24).round / 100.0 
     162 
     163  @err.puts "* Memory size before benchmarking: #{memsize}MB" 
     164 
     165  TIMES = @options["times"] || 1000 
     166  CNCRC = @options["concurrency"]|| 5   
     167 
     168  sleep 1 
     169 
     170  run_scenarios 
    85171 
    86172  ps = `ps aux #{pid}` 
    87173  memsize = (ps.split("\n")[1].split[5].to_f / 10.24).round / 100.0 
    88174 
    89   err.puts  
    90   err.puts "* Memory size after benchmarking: #{memsize}MB" 
     175  @err.puts  
     176  @err.puts "* Memory size after benchmarking: #{memsize}MB" 
    91177ensure 
    92178  `merb -k all`