Skip to content

Instantly share code, notes, and snippets.

@kwatch
Last active January 7, 2016 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kwatch/c634e91d2d6a6c4b1d40 to your computer and use it in GitHub Desktop.
Save kwatch/c634e91d2d6a6c4b1d40 to your computer and use it in GitHub Desktop.
Ruby on Rails, Sinatra, Rack+Request+Response, Keight.rb のベンチマークスクリプト
# -*- coding: utf-8 -*-
require 'sinatra/base'
require 'rack'
require 'rack/protection'
require 'rack/protection/frame_options'
require 'rack/protection/http_origin'
require 'rack/protection/ip_spoofing'
require 'rack/protection/json_csrf'
require 'rack/protection/path_traversal'
require 'rack/protection/xss_header'
require './keight'
##
## Ruby on Rails
##
ENV['RAILS_ENV'] = 'production'
#ENV['RAILS_ENV'] = 'development'
require ::File.expand_path('../config/environment', __FILE__)
rails_app = Rails.application
##
## Sinatra
##
ENV['RACK_ENV'] = 'production'
class SinaApp < Sinatra::Base
configure do
disable :sessions
disable :logging
disable :protection
disable :x_cascade
end
get "/api/hello" do
"<h1>Hello</h1>"
end
get "/api/hello/:id" do
id = params[:id]
"<h1>Hello: id=#{id}</h1>"
end
end
sina_app = SinaApp.new
##
## Rack + Rack::Request + Rack::Response
##
class RackApp
def call(env)
req = Rack::Request.new(env)
resp = Rack::Response.new
content = "<h1>Hello</h1>"
resp.headers['Content-Type'] = "text/html; charset=utf-8"
resp.headers['Content-Length'] = content.bytesize.to_s
[resp.status, resp.headers, [content]]
end
end
rack_app = RackApp.new
##
## Keight
##
class HelloAction < K8::Action
mapping '' , :GET=>:do_index
mapping '/{id}' , :GET=>:do_show
def do_index
"<h1>Hello</h1>"
end
def do_show(id)
"<h1>Hello: id=#{id}</h1>"
end
end
opts = {urlpath_cache_size: 0}
k8_app = K8::RackApplication.new([
['/api', [
['/hello', HelloAction],
]],
], opts)
##
## helpers
##
require 'pp'
require 'rack'
require 'rack/mock'
def _chk(tuple)
tuple[0] == 200 or raise "200 expected but got #{tuple[0]}"
tuple[1]['Content-Type'] or raise "content type expected"
tuple[1]['Content-Type'] =~ /text\/html/ or raise "unexpected content type: #{tuple[1]['Content-Type']}"
GC.start
end
$environ = Rack::MockRequest.env_for("http://localhost/")
$environ['REQUEST_METHOD'] = 'GET'
def newenv(path)
env = $environ.dup
env['PATH_INFO'] = path
env
end
##
## warm up
##
tuple = rails_app.call(newenv('/api/hello/123'))
#$stderr.puts "\033[0;31m*** debug: tuple=#{PP.pp(tuple,'')}\033[0m"
_chk(tuple)
tuple = sina_app.call(newenv('/api/hello/123'))
#$stderr.puts "\033[0;31m*** debug: tuple=#{PP.pp(tuple,'')}\033[0m"
_chk(tuple)
tuple = rack_app.call(newenv('/api/hello/123'))
#$stderr.puts "\033[0;31m*** debug: tuple=#{PP.pp(tuple,'')}\033[0m"
_chk(tuple)
tuple = k8_app.call(newenv('/api/hello/123'))
#$stderr.puts "\033[0;31m*** debug: tuple=#{PP.pp(tuple,'')}\033[0m"
_chk(tuple)
##
## benchmarks
##
require './benchmarker'
N = ($N || 10000).to_i
Benchmarker.new(:width=>30, :loop=>N) do |bm|
puts ""
puts "** rack: #{Rack.release}"
puts "** rails: #{Rails.version}"
puts "** sinatra: #{Sinatra::VERSION}"
puts "** keight: #{K8::RELEASE}"
puts ""
puts "** N=#{N}"
bm.empty_task do
newenv('/api/hello')
end
bm.task "(RoR) GET /api/hello" do
tuple = rails_app.call(newenv('/api/hello'))
end
_chk(tuple)
bm.task "(RoR) GET /api/hello/123" do
tuple = rails_app.call(newenv('/api/hello/123'))
end
_chk(tuple)
bm.task "(Sina) GET /api/hello" do
tuple = sina_app.call(newenv('/api/hello'))
end
_chk(tuple)
bm.task "(Sina) GET /api/hello/123" do
tuple = sina_app.call(newenv('/api/hello/123'))
end
_chk(tuple)
bm.task "(Rack) GET /api/hello" do
tuple = rack_app.call(newenv('/api/hello'))
end
_chk(tuple)
bm.task "(K8) GET /api/hello" do
tuple = k8_app.call(newenv('/api/hello'))
end
_chk(tuple)
bm.task "(K8) GET /api/hello/123" do
tuple = k8_app.call(newenv('/api/hello/123'))
end
_chk(tuple)
end
__END__
##
## example result
##
$ ruby -s bench.rb -N=100000
benchmarker.rb: release 0.0.0
RUBY_VERSION: 2.2.3
RUBY_PATCHLEVEL: 173
RUBY_PLATFORM: x86_64-darwin14
** rack: 1.6.4
** rails: 4.2.4
** sinatra: 1.4.6
** keight: 0.2.0
** N=100000
## user sys total real
(Empty) 0.7800 0.0200 0.8000 0.8004
(RoR) GET /api/hello 71.8300 1.9400 73.7700 73.8714
(RoR) GET /api/hello/123 75.9400 2.1200 78.0600 78.2206
(Sina) GET /api/hello 11.7000 2.7000 14.4000 14.4127
(Sina) GET /api/hello/123 13.0600 2.7500 15.8100 15.8382
(Rack) GET /api/hello 1.0000 -0.0200 0.9800 0.9896
(K8) GET /api/hello 0.7700 -0.0200 0.7500 0.7551
(K8) GET /api/hello/123 1.0700 -0.0100 1.0600 1.0559
## Ranking real
(K8) GET /api/hello 0.7551 (100.0%) ********************
(Rack) GET /api/hello 0.9896 ( 76.3%) ***************
(K8) GET /api/hello/123 1.0559 ( 71.5%) **************
(Sina) GET /api/hello 14.4127 ( 5.2%) *
(Sina) GET /api/hello/123 15.8382 ( 4.8%) *
(RoR) GET /api/hello 73.8714 ( 1.0%)
(RoR) GET /api/hello/123 78.2206 ( 1.0%)
## Matrix real [01] [02] [03] [04] [05] [06] [07]
[01] (K8) GET /api/hello 0.7551 100.0% 131.1% 139.8% 1908.8% 2097.6% 9783.3% 10359.2%
[02] (Rack) GET /api/hello 0.9896 76.3% 100.0% 106.7% 1456.4% 1600.5% 7464.9% 7904.4%
[03] (K8) GET /api/hello/123 1.0559 71.5% 93.7% 100.0% 1365.0% 1500.0% 6996.1% 7408.0%
[04] (Sina) GET /api/hello 14.4127 5.2% 6.9% 7.3% 100.0% 109.9% 512.5% 542.7%
[05] (Sina) GET /api/hello/123 15.8382 4.8% 6.2% 6.7% 91.0% 100.0% 466.4% 493.9%
[06] (RoR) GET /api/hello 73.8714 1.0% 1.3% 1.4% 19.5% 21.4% 100.0% 105.9%
[07] (RoR) GET /api/hello/123 78.2206 1.0% 1.3% 1.3% 18.4% 20.2% 94.4% 100.0%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment