kamal-railsbench 0.9.9.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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