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
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
4
+
5
+ require 'fileutils'
6
+ require 'railsbench/benchmark_specs'
7
+
8
+ ARGV.each do |file_name|
9
+ backup_file_name = file_name + '~'
10
+ FileUtils.mv(file_name, backup_file_name)
11
+ File.open(backup_file_name) do |infile|
12
+ bench_name = Hash.new{ |hash,key| hash[key] = key }
13
+ File.open(file_name, "w") do |outfile|
14
+ infile.each_line do |line|
15
+ case line
16
+ when /-bm=([^\s]+)/
17
+ # $stderr.puts "-bm=#{$1}"
18
+ outfile.puts(line)
19
+ benchmarks = BenchmarkSpec.load($1)
20
+ benchmarks.each{|spec| bench_name[spec.uri] = spec.name}
21
+ when /^(.*)(\s+[\d\.]+\s+[\d\.]+\s+[\d\.]+\s+\(\s*[\d\.]+\s*\))$/
22
+ l = $1.length
23
+ # $stderr.printf "%-#{l}s%s\n", $1.strip, $2
24
+ outfile.printf "%-#{l}s%s\n", bench_name[$1.strip], $2
25
+ else
26
+ outfile.puts(line)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ __END__
34
+
35
+ # Copyright (C) 2007, 2008 Stefan Kaes
36
+ #
37
+ # This program is free software; you can redistribute it and/or modify
38
+ # it under the terms of the GNU General Public License as published by
39
+ # the Free Software Foundation; either version 2 of the License, or
40
+ # (at your option) any later version.
41
+ #
42
+ # This program is distributed in the hope that it will be useful,
43
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
44
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45
+ # GNU General Public License for more details.
46
+ #
47
+ # You should have received a copy of the GNU General Public License
48
+ # along with this program; if not, write to the Free Software
49
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ unless ENV['RAILS_ROOT']
4
+ if File.directory?("config") && File.exists?("config/environment.rb")
5
+ ENV['RAILS_ROOT'] = File.expand_path(".")
6
+ else
7
+ $stderr.puts("\nperf_bench: can't generate benchmarks unless RAILS_ROOT is set")
8
+ $stderr.puts("\nbenchmarking aborted!")
9
+ exit 1
10
+ end
11
+ end
12
+
13
+ require "#{ENV['RAILS_ROOT']}/config/environment"
14
+ require 'application'
15
+
16
+ if ARGV.first == "help"
17
+ puts <<-"endhelp"
18
+ usage: railsbench generate_benchmarks -excluded_actions=<regexp> -excluded_controllers=<controller_list>
19
+ 1) loads your application\'s routes and generates a benchmarks.yml file
20
+ containing benchmark definitions for each route found
21
+ 2) for named routes, benchmark names are derived from the route name
22
+ 3) for routes defined via map.connect, the benchmark name is derived
23
+ from the controller and action
24
+ 4) for each controller, a benchmark consisting of all controller actions
25
+ is generated (named after the controller file name)
26
+ 5) generates a benchmark named 'all_controllers', consisting of all
27
+ benchmarks generated in step 4
28
+ endhelp
29
+ exit
30
+ end
31
+
32
+ excluded_controllers = ["application"]
33
+ excluded_actions = /delete|destroy/
34
+ ARGV.each do |arg|
35
+ excluded_controllers += $1.split(/, */).compact if arg =~ /-excluded_controllers=(.*)/
36
+ excluded_actions = Regexp.new($1.gsub(/,/, '|')) if arg =~ /-excluded_actions=(.*)/
37
+ end
38
+
39
+ benchmark_config = File.expand_path "#{RAILS_ROOT}/config/benchmarks.yml"
40
+
41
+ if File.exist? benchmark_config
42
+ benchmarks = YAML::load(File.open(benchmark_config)) || {}
43
+ else
44
+ benchmarks = {}
45
+ end
46
+
47
+ VALID_KEYS = %w(uri action controller new_session query_params)
48
+
49
+ def dump_entry(name, entry, io = $stdout)
50
+ io.puts "#{name}:"
51
+ if entry.is_a? Hash
52
+ VALID_KEYS.each do |key|
53
+ io.printf " %-15s %s\n", key + ':', entry[key] if entry.has_key? key
54
+ end
55
+ io.puts
56
+ elsif entry.is_a? String
57
+ io.printf " %s\n\n", entry
58
+ else
59
+ raise "unsupported YAML entry"
60
+ end
61
+ end
62
+
63
+ unless Rails::VERSION::STRING >= "1.2"
64
+ $stderr.puts "Rails version #{Rails::VERSION::STRING} is not supported. please use a 1.2.x or later variety."
65
+ exit 1
66
+ end
67
+
68
+ rs = ActionController::Routing::Routes
69
+
70
+ named_routes_map = rs.named_routes.to_a.inject({}){|h,(name,route)| h[route] = name; h}
71
+ controller_action_map = {}
72
+ has_default_route = false
73
+
74
+ out = File.open(benchmark_config, "w")
75
+
76
+ rs.routes.to_a.each do |route|
77
+ uri = route.segments.map(&:to_s).join
78
+ (has_default_route = true; next) if uri == "/:controller/:action/:id/"
79
+ controller = route.requirements[:controller].to_s
80
+ action = route.requirements[:action].to_s
81
+ controller_action = "#{controller}_#{action}"
82
+ file_name = "#{controller}_controller"
83
+ benchmark_name = (named_routes_map[route] || controller_action).to_s
84
+ entry = (benchmarks[benchmark_name] || {}).reverse_merge "uri" => uri, "controller" => controller, "action" => action
85
+ benchmarks.delete benchmark_name
86
+ if action =~ excluded_actions
87
+ $stderr.puts "ignored action: #{action}"
88
+ benchmarks[file_name] = ((benchmarks[file_name]||"").split(/, */) - [benchmark_name]).uniq.join(', ')
89
+ next
90
+ end
91
+ if excluded_controllers.include? controller
92
+ $stderr.puts "ignored controller: #{controller}"
93
+ benchmarks["all_controllers"] = ((benchmarks["all_controllers"]||"").split(/, */) - [file_name]).uniq.join(', ')
94
+ next
95
+ end
96
+ dump_entry benchmark_name, entry, out
97
+ controller_action_map[controller_action] = true
98
+ benchmarks[file_name] = ((benchmarks[file_name]||"").split(/, */) + [benchmark_name]).uniq.join(', ')
99
+ benchmarks["all_controllers"] = ((benchmarks["all_controllers"]||"").split(/, */) + [file_name]).uniq.join(', ')
100
+ end
101
+
102
+ if has_default_route
103
+ $stderr.puts "warning: you are still using the default route"
104
+ Dir["#{RAILS_ROOT}/app/controllers/*.rb"].each do |file|
105
+ file_name = File.basename(file).sub(/\.rb$/,'')
106
+ controller_name = file_name.sub(/_controller$/,'')
107
+ if excluded_controllers.include? controller_name
108
+ $stderr.puts "ignored controller: #{controller_name}"
109
+ benchmarks["all_controllers"] = ((benchmarks["all_controllers"]||"").split(/, */) - [file_name]).uniq.join(', ')
110
+ next
111
+ end
112
+ begin
113
+ controller = file_name.classify.constantize
114
+ controller.action_methods.map(&:to_s).each do |method|
115
+ benchmark_name = "#{controller_name}_#{method}"
116
+ next if controller_action_map[benchmark_name]
117
+ uri = rs.generate({:controller => controller_name ,:action => method},{})
118
+ entry = (benchmarks[benchmark_name] || {}).reverse_merge "uri" => uri, "controller" => controller_name, "action" => method
119
+ benchmarks.delete benchmark_name
120
+ if method =~ excluded_actions
121
+ $stderr.puts "ignored action: #{method}"
122
+ benchmarks[file_name] = ((benchmarks[file_name]||"").split(/, */) - [benchmark_name]).uniq.join(', ')
123
+ next
124
+ end
125
+ dump_entry benchmark_name, entry, out
126
+ benchmarks[file_name] = ((benchmarks[file_name]||"").split(/, */) + [benchmark_name]).uniq.join(', ')
127
+ benchmarks["all_controllers"] = ((benchmarks["all_controllers"]||"").split(/, */) + [file_name]).uniq.join(', ')
128
+ end
129
+ rescue MissingSourceFile, NoMethodError, ActionController::RoutingError
130
+ end
131
+ end
132
+ end
133
+
134
+ # dump remaining benchmarks
135
+ all_entry = benchmarks.delete "all_controllers"
136
+
137
+ benchmarks.delete_if do |k,v|
138
+ v.is_a?(Hash) && (v["action"].to_s =~ excluded_actions || v["controller"].to_s =~ excluded_controllers)
139
+ end
140
+
141
+ generated_controller_benchmarks, others = benchmarks.partition{|k,v| k =~ /_controller$/}
142
+
143
+ generated_controller_benchmarks.sort_by(&:first).each do |benchmark_name, entry|
144
+ dump_entry benchmark_name, entry, out
145
+ end
146
+
147
+ dump_entry "all_controllers", all_entry, out
148
+
149
+ others.each do |benchmark_name, entry|
150
+ dump_entry benchmark_name, entry, out
151
+ end
152
+
153
+ out.close unless out.nil?
154
+
155
+ __END__
156
+
157
+ # Copyright (C) 2007, 2008 Stefan Kaes
158
+ #
159
+ # This program is free software; you can redistribute it and/or modify
160
+ # it under the terms of the GNU General Public License as published by
161
+ # the Free Software Foundation; either version 2 of the License, or
162
+ # (at your option) any later version.
163
+ #
164
+ # This program is distributed in the hope that it will be useful,
165
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
166
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
167
+ # GNU General Public License for more details.
168
+ #
169
+ # You should have received a copy of the GNU General Public License
170
+ # along with this program; if not, write to the Free Software
171
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
4
+
5
+ unless ENV['RAILS_ROOT']
6
+ if File.directory?("config") && File.exists?("config/environment.rb")
7
+ ENV['RAILS_ROOT'] = File.expand_path(".")
8
+ else
9
+ $stderr.puts("\nperf_bench: can't benchmark unless RAILS_ROOT is set")
10
+ exit 1
11
+ end
12
+ end
13
+
14
+ trap("INT") { $stderr.puts("benchmarking aborted!"); exit!(-1) }
15
+
16
+ module Benchmark
17
+ if ENV['RAILS_BENCHMARK_FILE']
18
+ OUTPUT = File.open(ENV['RAILS_BENCHMARK_FILE'], "a+")
19
+ SYNC = false
20
+ else
21
+ OUTPUT = STDERR
22
+ end
23
+ end
24
+ require "benchmark"
25
+
26
+ Benchmark.bm(32) do |test|
27
+ test.report("loading environment") do
28
+ require 'railsbench/railsbenchmark'
29
+ require ENV['RAILS_ROOT'] + '/config/benchmarks'
30
+ end
31
+
32
+ trap("INT") do
33
+ $stderr.print "clearing database connections ..."
34
+ ActiveRecord::Base.send :clear_all_cached_connections! if ActiveRecord::Base.respond_to?(:clear_all_cached_connections)
35
+ ActiveRecord::Base.send :clear_all_connections! if ActiveRecord::Base.respond_to?(:clear_all_connections)
36
+ $stderr.puts
37
+ $stderr.puts "benchmarking aborted!"
38
+ exit!(-1)
39
+ end
40
+
41
+ benchmark_name = "default"
42
+ ARGV.each{ |arg| benchmark_name = $1 if arg =~ /-bm=([a-zA-Z_0-9]+)/ }
43
+
44
+ RAILS_BENCHMARKER.iterations = ARGV[0].to_i
45
+ RAILS_BENCHMARKER.setup_test_urls(benchmark_name)
46
+ RAILS_BENCHMARKER.establish_test_session
47
+ RAILS_BENCHMARKER.warmup
48
+
49
+ if ARGV.include?('-mix')
50
+ RAILS_BENCHMARKER.run_url_mix(test)
51
+ else
52
+ RAILS_BENCHMARKER.run_urls(test)
53
+ end
54
+ end
55
+
56
+ Benchmark::OUTPUT.close unless Benchmark::OUTPUT.nil? || !ENV['RAILS_BENCHMARK_FILE']
57
+
58
+ __END__
59
+
60
+ # Copyright (C) 2005-2008 Stefan Kaes
61
+ #
62
+ # This program is free software; you can redistribute it and/or modify
63
+ # it under the terms of the GNU General Public License as published by
64
+ # the Free Software Foundation; either version 2 of the License, or
65
+ # (at your option) any later version.
66
+ #
67
+ # This program is distributed in the hope that it will be useful,
68
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
69
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70
+ # GNU General Public License for more details.
71
+ #
72
+ # You should have received a copy of the GNU General Public License
73
+ # along with this program; if not, write to the Free Software
74
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
4
+ require 'railsbench/perf_info'
5
+
6
+ narrow = ARGV.delete('-narrow') || ARGV.delete('-n')
7
+ skip_urls = ARGV.delete('-skip_urls') || ARGV.delete('-s')
8
+
9
+ if ARGV.length < 2
10
+ $stderr.puts "perfcomp: not enough arguments!"
11
+ $stderr.puts "usage: perf_comp [-n[arrow]] [-s[kip_urls]] file1 file2"
12
+ exit 1
13
+ elsif ARGV.length > 2
14
+ $stderr.puts "perfcomp: too many arguments!"
15
+ $stderr.puts "usage: perf_comp [-n[arrow]] [-s[kip_urls]] file1 file2"
16
+ exit 1
17
+ end
18
+
19
+ files = []
20
+ configs = []
21
+ pi = []
22
+
23
+ ARGV.each do |arg|
24
+ files << File.open_or_die(arg)
25
+ pi << PerfInfo.new(files.last)
26
+ end
27
+
28
+ if pi[0].keys != pi[1].keys
29
+ $stderr.puts "perfcomp: can't compare runs with differing requests!"
30
+ exit 1
31
+ else
32
+ keys = pi[0].keys
33
+ end
34
+
35
+ iter1 = pi[0].iterations
36
+ iter2 = pi[1].iterations
37
+
38
+ if iter1 != iter2
39
+ $stderr.puts "perfcomp: scaling performance data: iterations of run 1 and run 2 differ: #{iter1}/#{iter2}"
40
+ end
41
+
42
+ if iter1 < iter2
43
+ c1 = iter2 / iter1
44
+ c2 = 1
45
+ else
46
+ c1 = 1
47
+ c2 = iter1 / iter2
48
+ end
49
+
50
+ printf "perf data file 1: #{files[0].path}\n"
51
+ printf " requests=#{iter1}, options=#{pi[0].options}\n\n"
52
+ printf "perf data file 2: #{files[1].path}\n"
53
+ printf " requests=#{iter2}, options=#{pi[1].options}\n\n"
54
+
55
+ if narrow
56
+ printf "%-3s %9s %9s %7s %7s %8s %8s %6s\n",
57
+ 'page', 'c1 real', 'c2 real', 'c1 r/s', 'c2 r/s', 'c1 ms/r', 'c2 ms/r', 'c1/c2'
58
+ else
59
+ printf "%-32s %9s %9s %7s %7s %8s %8s %6s\n",
60
+ 'page', 'c1 real', 'c2 real', 'c1 r/s', 'c2 r/s', 'c1 ms/r', 'c2 ms/r', 'c1/c2'
61
+ end
62
+
63
+ keys.each_with_index do |k, index|
64
+ # average runtime
65
+ t1 = pi[0].timings_mean(k) * c1
66
+ t2 = pi[1].timings_mean(k) * c2
67
+ urls1 = pi[0].requests_per_key
68
+ urls2 = pi[1].requests_per_key
69
+
70
+ # requests per second
71
+ rps1 = iter1*urls1*c1/t1
72
+ rps2 = iter2*urls2*c2/t2
73
+
74
+ # milliseconds per request
75
+ mspr1 = t1*1000/(iter1*urls1*c1)
76
+ mspr2 = t2*1000/(iter2*urls2*c2)
77
+
78
+ if narrow
79
+ printf "%2d: %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
80
+ (index+1), t1, t2, rps1, rps2, mspr1, mspr2, t1/t2
81
+ else
82
+ printf "%-32s %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
83
+ truncate(k), t1, t2, rps1, rps2, mspr1, mspr2, t1/t2
84
+ end
85
+ end
86
+
87
+ total_requests_run1 = pi[0].request_count
88
+ total_requests_run2 = pi[1].request_count
89
+ total_time1 = pi[0].total_time_mean * c1
90
+ total_time2 = pi[1].total_time_mean * c2
91
+ total_rps1 = total_requests_run1 * c1 / total_time1
92
+ total_rps2 = total_requests_run2 * c2 / total_time2
93
+ total_mspr1 = total_time1 * 1000 / (total_requests_run1 * c1)
94
+ total_mspr2 = total_time2 * 1000 / (total_requests_run2 * c2)
95
+
96
+ if narrow
97
+ printf "\n%4s %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
98
+ "all:", total_time1, total_time2,
99
+ total_rps1, total_rps2, total_mspr1, total_mspr2,
100
+ total_time1/total_time2
101
+ else
102
+ printf "\n%-32s %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
103
+ "all requests", total_time1, total_time2,
104
+ total_rps1, total_rps2, total_mspr1, total_mspr2,
105
+ total_time1/total_time2
106
+ end
107
+
108
+ if pi[0].gc_stats? && pi[1].gc_stats?
109
+ c1 = pi[0].gc_calls_mean
110
+ t1 = pi[0].gc_time_mean
111
+ c2 = pi[1].gc_calls_mean
112
+ t2 = pi[1].gc_time_mean
113
+ factor = (t1-t2==0) ? 1 : t1/t2
114
+
115
+ if narrow
116
+ printf "\n%-4s %9s %9s %7s %7s %8s %8s %6s\n",
117
+ "GC:", "c1 real", "c2 real", "c1 #gc", "c2 #gc", "c1 gc%", "c2 gc%", "c1/c2"
118
+ printf "%-4s %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
119
+ "", t1, t2, c1, c2, (t1/total_time1)*100, (t2/total_time2)*100, factor
120
+ else
121
+ printf "\n%-32s %9s %9s %7s %7s %8s %8s %6s\n",
122
+ "garbage collection stats", "c1 real", "c2 real", "c1 #gc", "c2 #gc", "c1 gc%", "c2 gc%", "c1/c2"
123
+ printf "%-32s %9.5f %9.5f %7.1f %7.1f %8.2f %8.2f %6.2f\n",
124
+ "", t1, t2, c1, c2, (t1/total_time1)*100, (t2/total_time2)*100, factor
125
+ end
126
+ end
127
+
128
+ if narrow and !skip_urls
129
+ puts "\nurls:"
130
+ keys.each_with_index do |k, index|
131
+ printf "%2d: %s\n", (index+1) , k
132
+ end
133
+ end
134
+
135
+ __END__
136
+
137
+ # Copyright (C) 2005-2008 Stefan Kaes
138
+ #
139
+ # This program is free software; you can redistribute it and/or modify
140
+ # it under the terms of the GNU General Public License as published by
141
+ # the Free Software Foundation; either version 2 of the License, or
142
+ # (at your option) any later version.
143
+ #
144
+ # This program is distributed in the hope that it will be useful,
145
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
146
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
147
+ # GNU General Public License for more details.
148
+ #
149
+ # You should have received a copy of the GNU General Public License
150
+ # along with this program; if not, write to the Free Software
151
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ options = ""
4
+ if ARGV.length!=2
5
+ $stderr.puts "usage: perf_diff_gc file1 file2"
6
+ exit 1
7
+ end
8
+ files=[]
9
+ ARGV.each do |arg|
10
+ fn = arg
11
+ fn = fn.sub(/^\/([cdefgh])(\/)/, '\1:\2') if RUBY_PLATFORM =~ /win32/
12
+ begin
13
+ if File.stat(fn).readable?
14
+ files << File.open(fn)
15
+ else
16
+ $stderr.print "file #{fn} is unreadable\n"
17
+ exit 1
18
+ end
19
+ rescue
20
+ $stderr.print "file #{fn} does not exist\n"
21
+ exit 1
22
+ end
23
+ end
24
+
25
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
26
+ require 'railsbench/gc_info'
27
+
28
+ printf "GC data file1: #{File.expand_path(files[0].path)}\n"
29
+ printf "GC data file2: #{File.expand_path(files[1].path)}\n\n"
30
+
31
+ gcis = files.map{|file| GCInfo.new(file)}
32
+ files.each{|file| file.close}
33
+
34
+ printf "number of requests: %d/%d\n", gcis[0].num_requests, gcis[1].num_requests
35
+
36
+ printf " %12s %12s %7s\n", "c1", "c2", "c1/c2"
37
+ printf "collections : %12.2f %12.2f %7.2f\n",
38
+ (n1 = gcis[0].collections),
39
+ (n2 = gcis[1].collections),
40
+ n1.to_f/n2
41
+ printf "garbage total : %12.2f %12.2f %7.2f\n",
42
+ (n1 = gcis[0].garbage_produced),
43
+ (n2 = gcis[1].garbage_produced),
44
+ n1.to_f/n2
45
+ printf "gc time total (sec) : %12.2f %12.2f %7.2f\n",
46
+ (n1 = gcis[0].time_total.to_f/1000),
47
+ (n2 = gcis[1].time_total.to_f/1000),
48
+ n1/n2
49
+ printf "garbage per request : %12.2f %12.2f %7.2f\n",
50
+ (n1 = gcis[0].garbage_produced.to_f/gcis[0].num_requests),
51
+ (n2 = gcis[1].garbage_produced.to_f/gcis[1].num_requests),
52
+ n1/n2
53
+ printf "requests per collection: %12.2f %12.2f %7.2f\n",
54
+ (n1 = gcis[0].num_requests.to_f/gcis[0].collections),
55
+ (n2 = gcis[1].num_requests.to_f/gcis[1].collections),
56
+ n1/n2
57
+
58
+ printf "\n %12s %12s %9s %9s %9s %9s\n",
59
+ "c1 mean", "c2 mean", "c1 min", "c2 min", "c1 max", "c2 max"
60
+
61
+ number_format = "%12.2f %12.2f %9d %9d %9d %9d"
62
+
63
+ printf "gc time(ms): #{number_format}\n",
64
+ gcis[0].time_mean, gcis[1].time_mean,
65
+ gcis[0].time_min, gcis[1].time_min,
66
+ gcis[0].time_max, gcis[1].time_max
67
+
68
+ printf "heap slots : #{number_format}\n",
69
+ gcis[0].processed_mean, gcis[1].processed_mean,
70
+ gcis[0].processed_min, gcis[1].processed_min,
71
+ gcis[0].processed_max, gcis[1].processed_max
72
+
73
+ printf "live : #{number_format}\n",
74
+ gcis[0].live_mean, gcis[1].live_mean,
75
+ gcis[0].live_min, gcis[1].live_min,
76
+ gcis[0].live_max, gcis[1].live_max
77
+
78
+ printf "freed : #{number_format}\n",
79
+ gcis[0].freed_mean, gcis[1].freed_mean,
80
+ gcis[0].freed_min, gcis[1].freed_min,
81
+ gcis[0].freed_max, gcis[1].freed_max
82
+
83
+ printf "freelist : #{number_format}\n",
84
+ gcis[0].freelist_mean, gcis[1].freelist_mean,
85
+ gcis[0].freelist_min, gcis[1].freelist_min,
86
+ gcis[0].freelist_max, gcis[1].freelist_max
87
+
88
+ printf "\ngarbage per object type:\n"
89
+ printf "%-12s %9s %9s %9s %7s\n", "object type", "#c1", "#c2", "c2-c1", "c2/c1"
90
+
91
+ GCInfo.object_types(gcis).each do |object_type|
92
+ n1, n2 = gcis[0].garbage_totals[object_type], gcis[1].garbage_totals[object_type]
93
+ printf "%-12s %9d %9d %9d %7.2f\n", object_type, n1, n2, n2-n1, n2.to_f/n1
94
+ end
95
+
96
+
97
+ __END__
98
+
99
+ # Copyright (C) 2005-2008 Stefan Kaes
100
+ #
101
+ # This program is free software; you can redistribute it and/or modify
102
+ # it under the terms of the GNU General Public License as published by
103
+ # the Free Software Foundation; either version 2 of the License, or
104
+ # (at your option) any later version.
105
+ #
106
+ # This program is distributed in the hope that it will be useful,
107
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
108
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109
+ # GNU General Public License for more details.
110
+ #
111
+ # You should have received a copy of the GNU General Public License
112
+ # along with this program; if not, write to the Free Software
113
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA