kamal-railsbench 0.9.9.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/BUGS +2 -0
  2. data/CHANGELOG +2124 -0
  3. data/GCPATCH +73 -0
  4. data/INSTALL +75 -0
  5. data/LICENSE +222 -0
  6. data/Manifest.txt +53 -0
  7. data/PROBLEMS +56 -0
  8. data/README +337 -0
  9. data/Rakefile +51 -0
  10. data/bin/railsbench +80 -0
  11. data/config/benchmarking.rb +21 -0
  12. data/config/benchmarks.rb +21 -0
  13. data/config/benchmarks.yml +2 -0
  14. data/images/empty.png +0 -0
  15. data/images/minus.png +0 -0
  16. data/images/plus.png +0 -0
  17. data/install.rb +70 -0
  18. data/latest_changes.txt +18 -0
  19. data/lib/benchmark.rb +576 -0
  20. data/lib/railsbench/benchmark.rb +576 -0
  21. data/lib/railsbench/benchmark_specs.rb +63 -0
  22. data/lib/railsbench/gc_info.rb +158 -0
  23. data/lib/railsbench/perf_info.rb +146 -0
  24. data/lib/railsbench/perf_utils.rb +202 -0
  25. data/lib/railsbench/railsbenchmark.rb +640 -0
  26. data/lib/railsbench/version.rb +9 -0
  27. data/lib/railsbench/write_headers_only.rb +15 -0
  28. data/postinstall.rb +12 -0
  29. data/ruby184gc.patch +516 -0
  30. data/ruby185gc.patch +562 -0
  31. data/ruby186gc.patch +564 -0
  32. data/ruby19gc.patch +2425 -0
  33. data/script/convert_raw_data_files +49 -0
  34. data/script/generate_benchmarks +171 -0
  35. data/script/perf_bench +74 -0
  36. data/script/perf_comp +151 -0
  37. data/script/perf_comp_gc +113 -0
  38. data/script/perf_diff +48 -0
  39. data/script/perf_diff_gc +53 -0
  40. data/script/perf_html +103 -0
  41. data/script/perf_plot +225 -0
  42. data/script/perf_plot_gc +254 -0
  43. data/script/perf_prof +87 -0
  44. data/script/perf_run +39 -0
  45. data/script/perf_run_gc +40 -0
  46. data/script/perf_table +104 -0
  47. data/script/perf_tex +58 -0
  48. data/script/perf_times +66 -0
  49. data/script/perf_times_gc +94 -0
  50. data/script/run_urls +57 -0
  51. data/setup.rb +1585 -0
  52. data/test/railsbench_test.rb +11 -0
  53. data/test/test_helper.rb +2 -0
  54. metadata +133 -0
data/README ADDED
@@ -0,0 +1,337 @@
1
+ Railsbench is a small collection of ruby scripts which make measuring
2
+ raw performance of rails apps a snap. All tests are run from the
3
+ command prompt, making performance regression testing easy.
4
+
5
+ In addition, a patch for the ruby garbage collector is provided, which
6
+ can be used to reduce the amount of time spent doing garbage
7
+ collection, trading memory for speed, as usual (see file GCPATCH for
8
+ details). Applying the patch will enhance performance data obtained
9
+ from the various scripts (and some won't run at all without the
10
+ patch).
11
+
12
+ This software was written and conceived by Stefan Kaes. The author can
13
+ be reached via email: <skaes@railsexpress.de>. Please send comments, bug
14
+ reports, patches or feature requests to this address.
15
+
16
+
17
+ FILES
18
+
19
+ railsbench.rb
20
+ - defines classes RailsBenchmark and RailsBenchmarkWithActiveRecordStore
21
+ switches:
22
+ -gcXXX : perform gc after XXX requests
23
+ -log[=level] : turn on rails logging (at given level)
24
+ -nocache : turn off rails caching
25
+ -path : print $: after loading rails and exit
26
+
27
+ config/bechmarks.yml
28
+ - specification of urls to benchmark
29
+ install into $RAILS_ROOT/config using `railsbench install'
30
+ (use railsbench install)
31
+
32
+ config/benchmarks.rb
33
+ - defines constant RAILSBENCH which is used by script perf_bench
34
+ modify this to add custom argument processing and to put data
35
+ into the session
36
+ install to $RAILS_ROOT/config using `railsbench install'
37
+
38
+ perf_bench n options
39
+ - main ruby script to run a given benchmark
40
+ switches (in addition to railsbench switches):
41
+ -mix : alternates urls in given benchmark
42
+
43
+ run_urls n options
44
+ - run a given benchmark (without benchmarking)
45
+ useful for checking response codes, like so:
46
+
47
+ run_urls 1 -bm=all | grep Status:
48
+
49
+ switches as for perf_bench plus
50
+ -warmup : run all urls once before measuring
51
+ -svlPV : run test using SVL Ruby Performance Validator
52
+ -svlMV : run test using SVL Ruby Memory Validator
53
+
54
+ perf_run n [ option-string [ config-name ] ]
55
+ - run a given benchmark, store performance data in a file
56
+ in directory $RAILS_PERF_DATA and print results
57
+
58
+ perf_diff n common-options option-string1 option-string2 [ config-name1 [ config-name2 ] ]
59
+ - run a given benchmark with two different sets of arguments
60
+ store data into directory $RAILS_PERF_DATA and print
61
+ comparison data
62
+
63
+ perf_loop n options
64
+ - used by perf_run and perf_diff
65
+ calls perf_bench $RAILS_PERF_RUNS times
66
+
67
+ perf_times file
68
+ - analyse and print performance data
69
+
70
+ perf_comp [-narrow] [-skip_urls] file1 file2
71
+ - compare two performance data sets and print results
72
+ -narrow => produce narrow output
73
+ -skip_urls => don't print url map (use with -narrow)
74
+
75
+ perf_html [-nocss] [-gc] [file]
76
+ - format output taken from perf_comp and produce a HTML table
77
+ for inclusion in HTML pages. Reads from standard input.
78
+ options:
79
+ -noccs suppress CSS output
80
+ -notable suppress table output
81
+ -gc include gc statistics
82
+
83
+ perf_run_gc n [ option-string [ config-name ] ]
84
+ - run a given benchmark, store performance data in a file
85
+ in directory $RAILS_PERF_DATA and print results
86
+ - requires Ruby GC patch (or Ruby Enterprise Edition)
87
+
88
+ perf_times_gc file
89
+ - analyse and print garbage collection statistics, which you
90
+ can produce by running perf_run_gc
91
+
92
+ perf_diff_gc n common-options option-string1 option-string2 [ config-name1 [ config-name2 ] ]
93
+ - run a given benchmark with two different sets of arguments
94
+ store GC data into directory $RAILS_PERF_DATA and print
95
+ GC stats comparison using perf_comp_gc
96
+ - requires Ruby GC patch
97
+
98
+ perf_comp_gc file1 file2
99
+ - compare two GC performance data sets and print results
100
+
101
+ perf_prof n [ option-string [ config-name ] ]
102
+ - run a given benchmark using ruby-prof for profiling,
103
+ store profile data in a HTML file in directory $RAILS_PERF_DATA
104
+ file name is computed from date and benchmark name as described above
105
+ but has a .html extension instead of .txt
106
+ - a number of options to steer ruby-prof are available:
107
+ -ruby_prof=number[/number]
108
+ sets threshold and min_percent for ruby-prof (defaults to 0.1/1)
109
+ -profile_type=stack|grind|flat|graph|multi
110
+ selects the profile format (defaults to stack)
111
+ -measure_mode=process_time|wall_time|cpu_time|allocations|memory
112
+ selects what to measure (default to wall_time)
113
+
114
+ perf_plot [ options ] file1 file2 ...
115
+ - plot performance data from raw performance files using gruff or gnuplot
116
+ see source for options
117
+
118
+ perf_plot_gc [ options ] file1 file2 ...
119
+ - plot data points from GC performance data stored in raw GC log files using gruff or gnuplot
120
+ this basically shows object type distribution across garbage collections
121
+ see source for options
122
+
123
+ perf_table [ options ] file1 file2 ...
124
+ - produces a tabular overview of perf data from given raw data files
125
+ see source for options
126
+
127
+ analyze_heap_dump file
128
+ - produces a html representation of a ruby heap dump.
129
+ useful for finding memory leaks.
130
+
131
+ ENVIRONMENT
132
+
133
+ RAILS_ROOT
134
+ - can be set to point to your rails app. if not set, railsbench can only
135
+ be called from the top level directory of your rails app
136
+
137
+ RAILS_PERF_DATA
138
+ - performance data sets will be stored into this directory
139
+ if not set, $HOME will be used
140
+
141
+ RAILS_PERF_RUNS
142
+ - the number of times perf_loop will run perf_bench on a single invocation
143
+ if not set, 3 runs will be performed
144
+
145
+ RAILS_BENCHMARK_FILE
146
+ - perf_bench sends its output to this file
147
+
148
+
149
+ INVOCATION
150
+
151
+ The gem version installs a driver script called 'railsbench' into
152
+ Ruby's bin directory. Individual commands can be called by prefixing
153
+ with railsbench. If you tire of typing railsbench all the time, you
154
+ can either define an alias (alias rb="railsbench"), or you can
155
+ include railsbench's script directory into your seach path. In this
156
+ case you need to run 'sudo railsbench postinstall' to make the
157
+ scripts executable.
158
+
159
+
160
+ USAGE
161
+
162
+ The two main scripts are named perf_run and perf_diff.
163
+
164
+ perf_run 100
165
+
166
+ runs the list of urls named "default" specified in benchmkarks.yml
167
+ (see below), requesting each url $RAILS_PERF_RUNS * 100 times.
168
+
169
+ perf_run 100 "-bm=list -aws"
170
+
171
+ runs the benchmark named 'list' and passes the expanded second
172
+ argument to the rails app. By processing arguments inside your
173
+ environment.rb file, you can set performance affecting options. For
174
+ example, you could load action web service only if -aws is passed and
175
+ measure the performance effect of omitting it.
176
+
177
+ Benchmark data is stored in directory $RAILS_PERF_DATA, which should
178
+ be set in your environment. If not set, $HOME is used. By default,
179
+ data is stored in file $RAILS_PERF_DATA/perf_run.$BENCHMARK.txt, where
180
+ BENCHMARK will be set according to the -bm option.
181
+
182
+ perf_run 100 "-bm=index -mail" mail
183
+
184
+ will store benchmark data in file
185
+
186
+ $RAILS_PERF_DATA/<current-date>.index.mail.txt.
187
+
188
+ You can get nicely formatted output of benchmark data by running
189
+
190
+ perf_times file
191
+
192
+ Script perf_run will automatically print the obtained data after
193
+ finishing the run using perf_times.
194
+
195
+ Script perf_diff runs a list of urls with two different option lists. So
196
+
197
+ perf_diff 100 "-bm=blogs -mysql_session" "-mail=0" "-mail=1" cf1 cf2
198
+
199
+ would run benchmark 'blogs' twice, first as
200
+
201
+ perf_run 100 "-bm=blogs -mysql_session -mail=0" cf1
202
+
203
+ and then
204
+
205
+ perf_run 100 "-bm=blogs -mysql_session -mail=1" cf2
206
+
207
+ printing a comparison of the bechmark data obtained after finishing
208
+ the second run. cf1 and cf2 can be omitted, in which case data is
209
+ stored in $RAILS_PERF_DATA/perf_run1.$BENCHMARK.txt and
210
+ $RAILS_PERF_DATA/perf_run2.$BENCHMARK.txt.
211
+
212
+ Script perf_bench can also be invoked manually to run a given
213
+ benchmark like so:
214
+
215
+ perf_bench 100 -bm=blogs -mysql_session -mail=1 >/dev/null
216
+
217
+ Performance data is sent to $RAILS_BENCHMARK_FILE, HTML output ends up
218
+ on stdout. If RAILS_BENCHMARK_FILE is not set, performance data is
219
+ sent to stderr.
220
+
221
+ Scripts perf_run_gc and perf_times_gc can be used to analyse GC performance:
222
+
223
+ perf_run_gc 100 "-bm=all -lib=stable11" gc.log
224
+ perf_times_gc gc.log
225
+
226
+ It will produce output looking like this:
227
+
228
+ GC data file: d:/perfdata/xp/perf_run.uncached.gc.txt
229
+
230
+ collections : 40
231
+ garbage total : 8188429
232
+ gc time total (sec) : 4.03
233
+ garbage per request : 2047.11
234
+ requests per collection: 100.00
235
+
236
+ mean stddev% min max
237
+ gc time(ms): 101.38 10.0 93.00 125.00
238
+ heap slots : 400000.00 0.0 400000.00 400000.00
239
+ live : 192914.31 0.2 191787.00 193197.00
240
+ freed : 207085.69 0.2 206803.00 208213.00
241
+ freelist : 0.00 0.0 0.00 0.00
242
+
243
+ Note that these numbers, especially requests per collection, are
244
+ only an approximation. This is due to the fact that perf_run_gc will
245
+ add one final garbage collection call at the end of the run. Of
246
+ course, higher number of iterations will produce more accurate
247
+ data. Also, if the benchmark lists several uris, garbage per request
248
+ will not give you meaningful information.
249
+
250
+
251
+ CONFIGURATION
252
+
253
+ Benchmarks are configured through file benchmarks.yml. Example:
254
+
255
+ default:
256
+ index, query, alpha
257
+
258
+ index:
259
+ uri: /test/index
260
+ new_session: true
261
+
262
+ query:
263
+ uri: /test/list
264
+ method: post
265
+ post_data: search_string=tomatoes
266
+
267
+ alpha:
268
+ uri: /test/alphabetic
269
+ query_string: page=7&letter=A
270
+
271
+ defines 4 benchmarks:
272
+
273
+ "index" will run (/test/index) using method GET
274
+ "query" will run (/test/list) using method POST
275
+ "alpha" will run (/test/alphabetic) using method GET
276
+ "default" will run benchmarks "index", "query" and "alpha"
277
+
278
+ uri: is mandatory, query_params: and new_session: are optional.
279
+
280
+ Instead of
281
+
282
+ uri: /test/alphabetic
283
+ query_string: page=7
284
+
285
+ one could have written
286
+
287
+ uri: /test/alphabetic?page=7&letter=A
288
+
289
+ A single test session is created before running the benchmarks and
290
+ stored in the sesion container of your choice. The corresponding
291
+ _session_id value is sent with each request. If you specifiy
292
+ new_session: true, railsbench will not send the session_id value, so
293
+ Rails will create a new session per request for the given benchmark.
294
+
295
+ Session data can either be set on the benchmarker instance, or
296
+ specified in the benchmark config file like so:
297
+
298
+ list_user_5:
299
+ uri: /test/list
300
+ method: post
301
+ post_data: search_string=tomatoes
302
+ session_data:
303
+ user_id: 5
304
+
305
+ benchmarks.yml is loaded using ERB. This makes it possible to avoid
306
+ using primary keys in the config file:
307
+
308
+ list_user_stefan:
309
+ uri: /test/list
310
+ method: post
311
+ post_data: search_string=tomatoes
312
+ session_data:
313
+ user_id: <%= User.find_by_login('stefan').id %>
314
+
315
+ An inital benchmark configuration file can be generated using command
316
+ generate_benchmarks.
317
+
318
+ generate_benchmarks -exclude_controllers=application,admin \
319
+ -exclude_actions=edit,delete,destroy
320
+
321
+ will generate a benchmark configuration file containing definitions
322
+ for the following benchmarks:
323
+
324
+ a) an entry for each named route
325
+ b) an entry for each route generated by unnamed route definitions
326
+ c) an entry for each controller, combining all actions (named xyz_controller)
327
+ d) an entry combining all controllers (all_controllers), combining all
328
+ benchmarks generated by step c.
329
+
330
+ After generating the benchmark configuration file you will need to
331
+ edit the benchmarks and change the placeholders in urls to real
332
+ values; i.e., change something like /blog/edit/:id to /blog/edit/235.
333
+
334
+ generate_benchmarks can be used on an existing configuration file. It
335
+ will keep exisiting entries, which will be moved to the end of the
336
+ config file. Thus it can be used to quickly update the config file
337
+ after you've added/deleted or renamed controllers and/or actions.
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'railsbench', 'version')
13
+
14
+ AUTHOR = "Stefan Kaes" # can also be an array of Authors
15
+ EMAIL = "skaes@railsexpress.de"
16
+ DESCRIPTION = "rails benchmarking tools"
17
+ GEM_NAME = "railsbench" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "railsbench" # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+ RELEASE_TYPES = %w(gem tar zip) # can use: gem, tar, zip
21
+
22
+ NAME = "railsbench"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = (ENV['VERSION'] ||= (Railsbench::VERSION::STRING + (REV ? ".#{REV}" : "")))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
+ RDOC_OPTS = ['--quiet', '--title', "railsbench documentation",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ # Generate all the Rake tasks
33
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
34
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
35
+ p.author = AUTHOR
36
+ p.description = DESCRIPTION
37
+ p.email = EMAIL
38
+ p.summary = DESCRIPTION
39
+ p.url = HOMEPATH
40
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
41
+ p.test_globs = ["test/**/*_test.rb"]
42
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
43
+ p.need_zip = true
44
+ p.spec_extras = {:has_rdoc => false}
45
+ p.changes = `cat latest_changes.txt`
46
+
47
+ # == Optional
48
+ #p.changes - A description of the release's latest changes.
49
+ #p.extra_deps - An array of rubygem dependencies.
50
+ #p.spec_extras - A hash of extra values to set in the gemspec.
51
+ end
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ RAILSBENCH_CMDS = %w(
4
+ analyze_heap_dump
5
+ base
6
+ generate_benchmarks
7
+ commands
8
+ convert_raw_data_files
9
+ help
10
+ install
11
+ path
12
+ perf_comp
13
+ perf_comp_gc
14
+ perf_diff
15
+ perf_diff_gc
16
+ perf_html
17
+ perf_plot
18
+ perf_plot_gc
19
+ perf_prof
20
+ perf_run
21
+ perf_run_gc
22
+ perf_table
23
+ perf_tex
24
+ perf_times
25
+ perf_times_gc
26
+ postinstall
27
+ readme
28
+ run_urls
29
+ ).inject({}){ |h, cmd| h[cmd] = cmd; h[cmd.sub('perf_', '')] = cmd; h}
30
+
31
+ cmd = ARGV.shift
32
+ unless real_cmd = RAILSBENCH_CMDS[cmd]
33
+ $stderr.puts "railsbench: unknown command: #{cmd}"
34
+ $stderr.puts "use one of: #{RAILSBENCH_CMDS.keys.sort.join(', ')}"
35
+ $stderr.puts "'railsbench help' displays README"
36
+ $stderr.puts "'railsbench cmd help' displays help for given command"
37
+ exit 1
38
+ end
39
+
40
+ RAILSBENCH_BASE = File.expand_path(File.dirname(__FILE__) + '/..')
41
+
42
+ case real_cmd
43
+ when 'commands'
44
+ puts RAILSBENCH_CMDS.keys.uniq.sort
45
+ when 'base'
46
+ puts "railsbench is installed in: #{RAILSBENCH_BASE}"
47
+ exit
48
+ when 'help', 'readme'
49
+ File.open("#{RAILSBENCH_BASE}/README").each_line{|l| puts l}
50
+ exit
51
+ when 'path'
52
+ puts "PATH=#{RAILSBENCH_BASE}/script:$PATH"
53
+ exit
54
+ when 'install', 'postinstall'
55
+ load "#{RAILSBENCH_BASE}/#{real_cmd}.rb"
56
+ when 'analyze_heap_dump', /plot/
57
+ load "#{RAILSBENCH_BASE}/script/#{real_cmd}"
58
+ else
59
+ unless ENV['RAILS_ROOT']
60
+ if File.exists? 'config/environment.rb'
61
+ ENV['RAILS_ROOT'] = File.expand_path '.'
62
+ else
63
+ $stderr.puts "railsbench: RAILS_ROOT not set and could not be configured automatically"
64
+ exit 1
65
+ end
66
+ end
67
+ unless File.exists? "#{ENV['RAILS_ROOT']}/config/benchmarks.yml"
68
+ $stderr.puts "railsbench: benchmarks.yml missing: run `railsbench install'"
69
+ exit 1
70
+ end
71
+ unless File.exists? "#{ENV['RAILS_ROOT']}/config/benchmarks.rb"
72
+ $stderr.puts "railsbench: benchmarks.rb missing: run `railsbench install'"
73
+ exit 1
74
+ end
75
+ unless File.exists? "#{ENV['RAILS_ROOT']}/config/environments/benchmarking.rb"
76
+ $stderr.puts "railsbench: environment 'benchmarking' missing: run `railsbench install'"
77
+ exit 1
78
+ end
79
+ load "#{RAILSBENCH_BASE}/script/#{real_cmd}"
80
+ end