#!/usr/bin/env ruby # Simple benchmark to compare Thin performance against # other webservers supported by Rack. # # Run with: # # ruby simple.rb [num of request] [print|graph] [concurrency levels] # require File.dirname(__FILE__) + '/../lib/thin' require File.dirname(__FILE__) + '/benchmarker' require 'optparse' options = { :requests => 1000, :concurrencies => [1, 10, 100], :keep_alive => false, :output => :table } OptionParser.new do |opts| opts.banner = "Usage: #{$PROGRAM_NAME} [options]" opts.on("-n", "--requests NUM", "Number of requests") { |num| options[:requests] = num.to_i } opts.on("-c", "--concurrencies EXP", "Concurrency levels") { |exp| options[:concurrencies] = eval(exp).to_a } opts.on("-k", "--keep-alive", "Use persistent connections") { options[:keep_alive] = true } opts.on("-t", "--table", "Output as text table") { options[:output] = :table } opts.on("-g", "--graph", "Output as graph") { options[:output] = :graph } opts.on_tail("-h", "--help", "Show this message") { puts opts; exit } end.parse!(ARGV) # benchmark output_type, %w(WEBrick Mongrel EMongrel Thin), request, levels b = Benchmarker.new b.requests = options[:requests] b.concurrencies = options[:concurrencies] b.keep_alive = options[:keep_alive] case options[:output] when :table puts 'server request concurrency req/s failures' puts '=' * 52 b.writer do |server, requests, concurrency, req_sec, failed| puts "#{server.ljust(8)} #{requests} #{concurrency.to_s.ljust(4)} #{req_sec.to_s.ljust(8)} #{failed}" end b.run! when :graph require '/usr/local/lib/ruby/gems/1.8/gems/gruff-0.2.9/lib/gruff' g = Gruff::Area.new g.title = "#{options[:requests]} requests" g.title << ' w/ Keep-Alive' if options[:keep_alive] g.x_axis_label = 'Concurrency' g.y_axis_label = 'Requests / sec' g.maximum_value = 0 g.minimum_value = 0 g.labels = {} b.concurrencies.each_with_index { |c, i| g.labels[i] = c.to_s } results = {} b.writer do |server, requests, concurrency, req_sec, failed| print '.' results[server] ||= [] results[server] << req_sec end b.run! puts results.each do |server, concurrencies| g.data(server, concurrencies) end g.write('bench.png') `open bench.png` end