derailed_benchmarks 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/README.md +134 -0
- data/derailed_benchmarks.gemspec +25 -0
- data/lib/derailed_benchmarks.rb +2 -0
- data/lib/derailed_benchmarks/tasks.rb +291 -0
- data/lib/derailed_benchmarks/version.rb +3 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: de696c65bb7e1fd25ec48fed45e6c8b6d7051c3f
|
4
|
+
data.tar.gz: 60f83ef96828857be4e501da08d95a449ab71a00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0852320d09632e4bb7a4e47dad84128708fa25b01c5ccd007d1ff66a4e05d1ed93097442759cee7d043dd3240d04f618a7b3e320b4e6eea0ac24fe1a5334bdc2
|
7
|
+
data.tar.gz: 085ea3fde49d10c5cc2c23d77a8c2891cb6888b33c176f573d027268260e6e8d14aee0f91b9d5eccc5993696c27ebe4b3683e3eef43e75b878d5bf665aea79af
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.DS_Store
|
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
## Derailed Benchmarks
|
2
|
+
|
3
|
+
A series of things you can use to benchmark a Rails app
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
Put this in your gemfile:
|
8
|
+
|
9
|
+
```
|
10
|
+
gem 'derailed_benchmarks' group: :development
|
11
|
+
```
|
12
|
+
|
13
|
+
Then run `$ bundle install`.
|
14
|
+
|
15
|
+
This part is **important** run this command to create a `perf.rake`
|
16
|
+
|
17
|
+
```
|
18
|
+
$ cat << EOF > perf.rake
|
19
|
+
require 'bundler'
|
20
|
+
Bundler.setup
|
21
|
+
|
22
|
+
require 'derailed_benchmarks'
|
23
|
+
require 'derailed_benchmarks/tasks'
|
24
|
+
EOF
|
25
|
+
```
|
26
|
+
|
27
|
+
The file should look like this:
|
28
|
+
|
29
|
+
```
|
30
|
+
$ cat perf.rake
|
31
|
+
require 'bundler'
|
32
|
+
Bundler.setup
|
33
|
+
|
34
|
+
require 'derailed_benchmarks'
|
35
|
+
require 'derailed_benchmarks/tasks'
|
36
|
+
```
|
37
|
+
|
38
|
+
This is done so the benchmarks will be loaded before your application, this is important for some benchmarks and less for others. This also prevents you from accidentally loading these benchmarks when you don't need them.
|
39
|
+
|
40
|
+
## Run
|
41
|
+
|
42
|
+
To find out the tasks available you can use `$ rake -f perf.rake -T` which essentially says use the file `perf.rake` and list all the tasks.
|
43
|
+
|
44
|
+
```
|
45
|
+
$ rake -f perf.rake -T
|
46
|
+
rake perf:allocated_objects # outputs allocated object diff after app is called TEST_COUNT times
|
47
|
+
rake perf:ips # ips
|
48
|
+
rake perf:mem # profiles ruby allocation
|
49
|
+
rake perf:ram_over_time # outputs ram usage over time
|
50
|
+
rake perf:require_bench # show memory usage caused by invoking require per gem
|
51
|
+
rake perf:stackprof # sampling stack time
|
52
|
+
rake perf:test # hits the url TEST_COUNT times
|
53
|
+
```
|
54
|
+
|
55
|
+
All the rake tasks accept configuration in the form of environment variables. For example, this command will measure the time it takes to hit your site `100,000` times:
|
56
|
+
|
57
|
+
```
|
58
|
+
$ rake -f perf.rake perf:test TEST_COUNT=100_000
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
## Config
|
63
|
+
|
64
|
+
Here are the common environment variables.
|
65
|
+
|
66
|
+
### PATH_TO_HIT
|
67
|
+
|
68
|
+
By default tasks will hit your homepage `/`. If you want to hit a different url use `PATH_TO_HIT` for example if you wanted to go to `users/new` you can execute:
|
69
|
+
|
70
|
+
```
|
71
|
+
PATH_TO_HIT=/users/new
|
72
|
+
```
|
73
|
+
|
74
|
+
### USE_SERVER
|
75
|
+
|
76
|
+
All tests are run without a webserver by default, if you want to use a webserver set `USE_SERVER` to a Rack::Server compliant server, such as `webrick`.
|
77
|
+
|
78
|
+
```
|
79
|
+
USE_SERVER=webrick
|
80
|
+
```
|
81
|
+
|
82
|
+
### TEST_COUNT
|
83
|
+
|
84
|
+
If the test contains an interation (most of them do), control how many times the test will loop before exiting with `TEST_COUNT`. To run `1` time you can execute
|
85
|
+
|
86
|
+
```
|
87
|
+
TEST_COUNT=1
|
88
|
+
```
|
89
|
+
|
90
|
+
Note some tasks have different defaults.
|
91
|
+
|
92
|
+
|
93
|
+
## Task Specific notes
|
94
|
+
|
95
|
+
|
96
|
+
### perf:mem
|
97
|
+
|
98
|
+
This task uses `memory_profiler` to see where memory is allocated while it is running. By default it will iterate once
|
99
|
+
|
100
|
+
|
101
|
+
### perf:ips
|
102
|
+
|
103
|
+
Determines the number of times your app can serve a web request each second (iterations per second). Higher number is better. Note this will be much larger if you do not use a server.
|
104
|
+
|
105
|
+
|
106
|
+
### perf:ram_over_time
|
107
|
+
|
108
|
+
Your app will use memory differently over time, this task records RSS memory usage every 5 seconds and outputs the value to STDOUT and to a file in `tmp/`. You can use this to build graphs (https://drive.google.com).
|
109
|
+
|
110
|
+
|
111
|
+
### perf:require_bench
|
112
|
+
|
113
|
+
Shows the amount of memory (RAM) each library takes up when it is required.
|
114
|
+
|
115
|
+
|
116
|
+
```
|
117
|
+
action_controller/railtie: 1.06 mb
|
118
|
+
action_controller: 0.72 mb
|
119
|
+
action_controller/metal/live: 0.38 mb
|
120
|
+
action_dispatch/http/response: 0.17 mb
|
121
|
+
rack/request: 0.05 mb
|
122
|
+
```
|
123
|
+
|
124
|
+
|
125
|
+
## License
|
126
|
+
|
127
|
+
MIT
|
128
|
+
|
129
|
+
|
130
|
+
## Acknowledgements
|
131
|
+
|
132
|
+
Most of the commands are wrappers around other libraries, go check them out. Also thanks to [@tenderlove](https://twitter.com/tenderlove) as I cribbed some of the Rails init code in `$ rake perf:setup` from one of his projects.
|
133
|
+
|
134
|
+
kthksbye [@schneems](https://twitter.com/schneems)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'derailed_benchmarks/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "derailed_benchmarks"
|
8
|
+
gem.version = DerailedBenchmarks::VERSION
|
9
|
+
gem.authors = ["Richard Schneeman"]
|
10
|
+
gem.email = ["richard.schneeman+rubygems@gmail.com"]
|
11
|
+
gem.description = %q{ Go faster, off the Rails }
|
12
|
+
gem.summary = %q{ Benchmarks designed to performance test your ENTIRE site }
|
13
|
+
gem.homepage = "https://github.com/schneems/derailed_benchmarks"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_dependency "memory_profiler", "~> 0"
|
22
|
+
gem.add_dependency "get_process_mem", "~> 0"
|
23
|
+
gem.add_dependency "benchmark-ips", "~> 2"
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,291 @@
|
|
1
|
+
namespace :perf do
|
2
|
+
task :setup do
|
3
|
+
require 'benchmark/ips'
|
4
|
+
require 'rack/file'
|
5
|
+
require 'time'
|
6
|
+
require 'rack/test'
|
7
|
+
|
8
|
+
require 'get_process_mem'
|
9
|
+
|
10
|
+
TEST_COUNT = (ENV['TEST_COUNT'] || ENV['CNT'] || 1_000).to_i
|
11
|
+
|
12
|
+
ENV["RAILS_ENV"] ||= "production"
|
13
|
+
ENV['RACK_ENV'] = ENV["RAILS_ENV"]
|
14
|
+
ENV["DISABLE_SPRING"] = "true"
|
15
|
+
|
16
|
+
ENV["SECRET_KEY_BASE"] ||= "foofoofoo"
|
17
|
+
|
18
|
+
ENV['LOG_LEVEL'] = "FATAL"
|
19
|
+
|
20
|
+
'.:lib:test:config'.split(':').each { |x| $: << x }
|
21
|
+
|
22
|
+
require 'application'
|
23
|
+
|
24
|
+
Rails.env = ENV["RAILS_ENV"]
|
25
|
+
|
26
|
+
APP = Rails.application
|
27
|
+
# puts APP.method(:initialize!).source_location
|
28
|
+
|
29
|
+
APP.initialize! unless APP.initialized?
|
30
|
+
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
31
|
+
ActiveRecord::Migration.verbose = true
|
32
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, nil)
|
33
|
+
|
34
|
+
APP.config.consider_all_requests_local = true
|
35
|
+
|
36
|
+
|
37
|
+
@app = Rack::MockRequest.new(APP)
|
38
|
+
|
39
|
+
puts "Booting: #{Rails.env}"
|
40
|
+
|
41
|
+
PATH_TO_HIT = ENV["PATH_TO_HIT"] || "/"
|
42
|
+
if server = ENV["USE_SERVER"]
|
43
|
+
@port = (3000..3900).to_a.sample
|
44
|
+
thread = Thread.new do
|
45
|
+
Rack::Server.start(app: APP, :Port => @port, environment: "none", server: server)
|
46
|
+
end
|
47
|
+
sleep 1
|
48
|
+
|
49
|
+
def call_app
|
50
|
+
`curl http://localhost:#{@port}#{PATH_TO_HIT} -s`
|
51
|
+
raise "Bad request: #{response.body}" unless $?.success?
|
52
|
+
end
|
53
|
+
else
|
54
|
+
def call_app
|
55
|
+
response = @app.get(PATH_TO_HIT)
|
56
|
+
raise "Bad request: #{response.body}" unless response.status == 200
|
57
|
+
response
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
desc "hits the url TEST_COUNT times"
|
64
|
+
task :test => [:setup] do
|
65
|
+
Benchmark.bm { |x|
|
66
|
+
x.report("#{TEST_COUNT} requests") {
|
67
|
+
TEST_COUNT.times {
|
68
|
+
call_app
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
task :stackprof => [:setup] do
|
75
|
+
# [:wall, :cpu, :object]
|
76
|
+
require 'stackprof'
|
77
|
+
file = "tmp/#{Time.now.iso8601}-stackprof-cpu-myapp.dump"
|
78
|
+
StackProf.run(mode: :cpu, out: file) do
|
79
|
+
Rake::Task["perf:test"].invoke
|
80
|
+
end
|
81
|
+
cmd = "stackprof #{file}"
|
82
|
+
puts "Running `#{cmd}`. Execute `stackprof --help` for more info"
|
83
|
+
puts `#{cmd}`
|
84
|
+
end
|
85
|
+
|
86
|
+
task :kernel_require_patch do
|
87
|
+
require 'get_process_mem'
|
88
|
+
|
89
|
+
class RequireTree
|
90
|
+
attr_reader :name
|
91
|
+
attr_accessor :cost
|
92
|
+
|
93
|
+
def initialize(name)
|
94
|
+
@name = name
|
95
|
+
@children = {}
|
96
|
+
end
|
97
|
+
|
98
|
+
def <<(tree)
|
99
|
+
@children[tree.name] = tree
|
100
|
+
end
|
101
|
+
|
102
|
+
def [](name)
|
103
|
+
@children[name]
|
104
|
+
end
|
105
|
+
|
106
|
+
def children
|
107
|
+
@children.values
|
108
|
+
end
|
109
|
+
|
110
|
+
def cost
|
111
|
+
@cost || 0
|
112
|
+
end
|
113
|
+
|
114
|
+
def sorted_children
|
115
|
+
children.sort { |c1, c2| c2.cost <=> c1.cost }
|
116
|
+
end
|
117
|
+
|
118
|
+
def print_sorted_children(level = 0)
|
119
|
+
return if cost < ENV['CUT_OFF'].to_f
|
120
|
+
puts " " * level + "#{name}: #{cost.round(4)} mb"
|
121
|
+
level += 1
|
122
|
+
sorted_children.each do |child|
|
123
|
+
child.print_sorted_children(level)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
module Kernel
|
131
|
+
alias :original_require :require
|
132
|
+
REQUIRE_STACK = []
|
133
|
+
|
134
|
+
def require file
|
135
|
+
Kernel.require(file)
|
136
|
+
end
|
137
|
+
|
138
|
+
class << self
|
139
|
+
alias :original_require :require
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
TOP_REQUIRE = RequireTree.new("TOP")
|
144
|
+
REQUIRE_STACK.push(TOP_REQUIRE)
|
145
|
+
|
146
|
+
Kernel.define_singleton_method(:require) do |file|
|
147
|
+
mem = GetProcessMem.new
|
148
|
+
node = RequireTree.new(file)
|
149
|
+
|
150
|
+
parent = REQUIRE_STACK.last
|
151
|
+
parent << node
|
152
|
+
REQUIRE_STACK.push(node)
|
153
|
+
begin
|
154
|
+
before = mem.mb
|
155
|
+
original_require file
|
156
|
+
ensure
|
157
|
+
REQUIRE_STACK.pop # node
|
158
|
+
after = mem.mb
|
159
|
+
end
|
160
|
+
node.cost = after - before
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
desc "show memory usage caused by invoking require per gem"
|
165
|
+
task :require_bench => [:kernel_require_patch , :setup] do
|
166
|
+
ENV['CUT_OFF'] ||= "0.3"
|
167
|
+
puts "## Impact of `require <file>` on RAM"
|
168
|
+
puts
|
169
|
+
puts "Showing all `require <file>` calls that consume #{ENV['CUT_OFF']} mb or more of RSS"
|
170
|
+
puts "Configure with `CUT_OFF=0` for all entries or `CUT_OFF=5` for few entries"
|
171
|
+
|
172
|
+
puts "Note: Files only count against RAM on their first load."
|
173
|
+
puts " If multiple libraries require the same file, then"
|
174
|
+
puts " the 'cost' only shows up under the first library"
|
175
|
+
puts
|
176
|
+
|
177
|
+
call_app
|
178
|
+
|
179
|
+
TOP_REQUIRE.sorted_children.each do |child|
|
180
|
+
child.print_sorted_children
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
desc "outputs ram usage over time"
|
185
|
+
task :ram_over_time => [:setup] do
|
186
|
+
puts "PID: #{Process.pid}"
|
187
|
+
ram = GetProcessMem.new
|
188
|
+
@keep_going = true
|
189
|
+
begin
|
190
|
+
unless ENV["SKIP_FILE_WRITE"]
|
191
|
+
ruby = `ruby -v`
|
192
|
+
FileUtils.mkdir_p("tmp")
|
193
|
+
file = File.open("tmp/#{Time.now.iso8601}-#{ruby}-memory-#{TEST_COUNT}-times.txt", 'w')
|
194
|
+
file.sync = true
|
195
|
+
end
|
196
|
+
|
197
|
+
ram_thread = Thread.new do
|
198
|
+
while @keep_going
|
199
|
+
mb = ram.mb
|
200
|
+
STDOUT.puts mb
|
201
|
+
file.puts mb unless ENV["SKIP_FILE_WRITE"]
|
202
|
+
sleep 5
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
TEST_COUNT.times {
|
207
|
+
call_app
|
208
|
+
}
|
209
|
+
ensure
|
210
|
+
@keep_going = false
|
211
|
+
ram_thread.join
|
212
|
+
file.close unless ENV["SKIP_FILE_WRITE"]
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
desc "iterations per second"
|
217
|
+
task :ips => [:setup] do
|
218
|
+
Benchmark.ips do |x|
|
219
|
+
x.report("ips") { call_app }
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
desc "outputs GC::Profiler.report data while app is called TEST_COUNT times"
|
224
|
+
task :gc => [:setup] do
|
225
|
+
GC::Profiler.enable
|
226
|
+
TEST_COUNT.times { call_app }
|
227
|
+
GC::Profiler.report
|
228
|
+
GC::Profiler.disable
|
229
|
+
end
|
230
|
+
|
231
|
+
task :foo => [:setup] do
|
232
|
+
require 'objspace'
|
233
|
+
call_app
|
234
|
+
|
235
|
+
before = Hash.new { 0 }
|
236
|
+
after = Hash.new { 0 }
|
237
|
+
after_size = Hash.new { 0 }
|
238
|
+
GC.start
|
239
|
+
GC.disable
|
240
|
+
|
241
|
+
TEST_COUNT.times { call_app }
|
242
|
+
|
243
|
+
rvalue_size = GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
|
244
|
+
ObjectSpace.each_object do |obj|
|
245
|
+
after[obj.class] += 1
|
246
|
+
memsize = ObjectSpace.memsize_of(obj) + rvalue_size
|
247
|
+
# compensate for API bug
|
248
|
+
memsize = rvalue_size if memsize > 100_000_000_000
|
249
|
+
after_size[obj.class] += memsize
|
250
|
+
end
|
251
|
+
|
252
|
+
require 'pp'
|
253
|
+
pp after.sort {|(k,v), (k2, v2)| v2 <=> v }
|
254
|
+
puts "========="
|
255
|
+
puts
|
256
|
+
puts
|
257
|
+
pp after_size.sort {|(k,v), (k2, v2)| v2 <=> v }
|
258
|
+
end
|
259
|
+
|
260
|
+
desc "outputs allocated object diff after app is called TEST_COUNT times"
|
261
|
+
task :allocated_objects => [:setup] do
|
262
|
+
call_app
|
263
|
+
GC.start
|
264
|
+
GC.disable
|
265
|
+
start = ObjectSpace.count_objects
|
266
|
+
TEST_COUNT.times { call_app }
|
267
|
+
finish = ObjectSpace.count_objects
|
268
|
+
GC.enable
|
269
|
+
finish.each do |k,v|
|
270
|
+
puts k => (v - start[k]) / TEST_COUNT.to_f
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
desc "profiles ruby allocation"
|
276
|
+
task :mem => [:setup] do
|
277
|
+
require 'memory_profiler'
|
278
|
+
call_app
|
279
|
+
GC.start
|
280
|
+
|
281
|
+
num = Integer(ENV["TEST_COUNT"] || 1)
|
282
|
+
opts = {}
|
283
|
+
opts[:ignore_files] = /#{ENV['IGNORE_FILES_REGEXP']}/ if ENV['IGNORE_FILES_REGEXP']
|
284
|
+
puts "Running #{num} times"
|
285
|
+
report = MemoryProfiler.report(opts) do
|
286
|
+
num.times { call_app }
|
287
|
+
end
|
288
|
+
report.pretty_print
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: derailed_benchmarks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Richard Schneeman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: memory_profiler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: get_process_mem
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: benchmark-ips
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2'
|
55
|
+
description: " Go faster, off the Rails "
|
56
|
+
email:
|
57
|
+
- richard.schneeman+rubygems@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- README.md
|
64
|
+
- derailed_benchmarks.gemspec
|
65
|
+
- lib/derailed_benchmarks.rb
|
66
|
+
- lib/derailed_benchmarks/tasks.rb
|
67
|
+
- lib/derailed_benchmarks/version.rb
|
68
|
+
homepage: https://github.com/schneems/derailed_benchmarks
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.2.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Benchmarks designed to performance test your ENTIRE site
|
92
|
+
test_files: []
|
93
|
+
has_rdoc:
|