railsbench 0.9.2 → 0.9.8
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.
- data/CHANGELOG +1808 -451
- data/GCPATCH +73 -0
- data/INSTALL +5 -0
- data/Manifest.txt +23 -13
- data/PROBLEMS +0 -0
- data/README +23 -7
- data/Rakefile +1 -2
- data/bin/railsbench +7 -1
- data/config/benchmarking.rb +0 -0
- data/config/benchmarks.rb +3 -2
- data/config/benchmarks.yml +0 -0
- data/images/empty.png +0 -0
- data/images/minus.png +0 -0
- data/images/plus.png +0 -0
- data/install.rb +1 -1
- data/latest_changes.txt +18 -0
- data/lib/benchmark.rb +0 -0
- data/lib/railsbench/benchmark.rb +576 -0
- data/lib/railsbench/benchmark_specs.rb +63 -63
- data/lib/railsbench/gc_info.rb +38 -3
- data/lib/railsbench/perf_info.rb +1 -1
- data/lib/railsbench/perf_utils.rb +202 -179
- data/lib/railsbench/railsbenchmark.rb +213 -55
- data/lib/railsbench/version.rb +9 -9
- data/lib/railsbench/write_headers_only.rb +15 -15
- data/postinstall.rb +0 -0
- data/ruby185gc.patch +56 -29
- data/ruby186gc.patch +564 -0
- data/ruby19gc.patch +2425 -0
- data/script/convert_raw_data_files +49 -49
- data/script/generate_benchmarks +14 -4
- data/script/perf_bench +12 -8
- data/script/perf_comp +1 -1
- data/script/perf_comp_gc +9 -1
- data/script/perf_diff +2 -2
- data/script/perf_diff_gc +2 -2
- data/script/perf_html +1 -1
- data/script/perf_plot +192 -75
- data/script/perf_plot_gc +213 -74
- data/script/perf_prof +29 -10
- data/script/perf_run +2 -2
- data/script/perf_run_gc +2 -2
- data/script/perf_table +2 -2
- data/script/perf_tex +1 -1
- data/script/perf_times +6 -6
- data/script/perf_times_gc +14 -2
- data/script/run_urls +16 -10
- data/setup.rb +0 -0
- data/test/railsbench_test.rb +0 -0
- data/test/test_helper.rb +2 -0
- metadata +77 -55
@@ -1,63 +1,63 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
require 'yaml'
|
3
|
-
require 'erb'
|
4
|
-
|
5
|
-
class BenchmarkSpec < DelegateClass(Hash)
|
6
|
-
attr_accessor :name
|
7
|
-
|
8
|
-
READERS = %w(uri method post_data query_string new_session action controller session_data)
|
9
|
-
READERS.each do |method|
|
10
|
-
define_method(method) { self[method] }
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(name, hash)
|
14
|
-
super(hash)
|
15
|
-
@name = name
|
16
|
-
end
|
17
|
-
|
18
|
-
def inspect
|
19
|
-
"BenchmarkSpec(#{name},#{super})"
|
20
|
-
end
|
21
|
-
|
22
|
-
class << self
|
23
|
-
def load(name, file_name = nil)
|
24
|
-
unless file_name
|
25
|
-
file_name = ENV['RAILS_ROOT'] + "/config/benchmarks.yml"
|
26
|
-
end
|
27
|
-
@@specs = YAML::load(ERB.new(IO.read(file_name)).result)
|
28
|
-
raise "There is no benchmark named '#{name}'" unless @@specs[name]
|
29
|
-
parse(@@specs, name)
|
30
|
-
end
|
31
|
-
|
32
|
-
def parse(specs, name)
|
33
|
-
spec = specs[name]
|
34
|
-
if spec.is_a?(String)
|
35
|
-
spec.split(/, */).collect!{ |n| parse(specs, n) }.flatten
|
36
|
-
elsif spec.is_a?(Hash)
|
37
|
-
[ BenchmarkSpec.new(name,spec) ]
|
38
|
-
elsif spec.is_a?(Array)
|
39
|
-
spec.collect{|n| parse(specs, n)}.flatten
|
40
|
-
else
|
41
|
-
raise "oops: unknown entry type in benchmark specification"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
__END__
|
48
|
-
|
49
|
-
# Copyright (C) 2007 Stefan Kaes
|
50
|
-
#
|
51
|
-
# This program is free software; you can redistribute it and/or modify
|
52
|
-
# it under the terms of the GNU General Public License as published by
|
53
|
-
# the Free Software Foundation; either version 2 of the License, or
|
54
|
-
# (at your option) any later version.
|
55
|
-
#
|
56
|
-
# This program is distributed in the hope that it will be useful,
|
57
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
58
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
59
|
-
# GNU General Public License for more details.
|
60
|
-
#
|
61
|
-
# You should have received a copy of the GNU General Public License
|
62
|
-
# along with this program; if not, write to the Free Software
|
63
|
-
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
1
|
+
require 'delegate'
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
class BenchmarkSpec < DelegateClass(Hash)
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
READERS = %w(uri method post_data query_string new_session action controller session_data xhr raw_data)
|
9
|
+
READERS.each do |method|
|
10
|
+
define_method(method) { self[method] }
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(name, hash)
|
14
|
+
super(hash)
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"BenchmarkSpec(#{name},#{super})"
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def load(name, file_name = nil)
|
24
|
+
unless file_name
|
25
|
+
file_name = ENV['RAILS_ROOT'] + "/config/benchmarks.yml"
|
26
|
+
end
|
27
|
+
@@specs = YAML::load(ERB.new(IO.read(file_name)).result)
|
28
|
+
raise "There is no benchmark named '#{name}'" unless @@specs[name]
|
29
|
+
parse(@@specs, name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse(specs, name)
|
33
|
+
spec = specs[name]
|
34
|
+
if spec.is_a?(String)
|
35
|
+
spec.split(/, */).collect!{ |n| parse(specs, n) }.flatten
|
36
|
+
elsif spec.is_a?(Hash)
|
37
|
+
[ BenchmarkSpec.new(name,spec) ]
|
38
|
+
elsif spec.is_a?(Array)
|
39
|
+
spec.collect{|n| parse(specs, n)}.flatten
|
40
|
+
else
|
41
|
+
raise "oops: unknown entry type in benchmark specification"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
__END__
|
48
|
+
|
49
|
+
# Copyright (C) 2007, 2008 Stefan Kaes
|
50
|
+
#
|
51
|
+
# This program is free software; you can redistribute it and/or modify
|
52
|
+
# it under the terms of the GNU General Public License as published by
|
53
|
+
# the Free Software Foundation; either version 2 of the License, or
|
54
|
+
# (at your option) any later version.
|
55
|
+
#
|
56
|
+
# This program is distributed in the hope that it will be useful,
|
57
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
58
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
59
|
+
# GNU General Public License for more details.
|
60
|
+
#
|
61
|
+
# You should have received a copy of the GNU General Public License
|
62
|
+
# along with this program; if not, write to the Free Software
|
63
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
data/lib/railsbench/gc_info.rb
CHANGED
@@ -25,6 +25,15 @@ require "set"
|
|
25
25
|
# kept 0173634 / freed 0002389 objects of type NODE
|
26
26
|
# GC time: 47 msec
|
27
27
|
|
28
|
+
# Sentinel:
|
29
|
+
# HEAP[ 0]: size= 300000
|
30
|
+
# HEAP[ 1]: size= 600000
|
31
|
+
# ...
|
32
|
+
# number of requests processed: 1000
|
33
|
+
# 128334 nodes malloced for 17345 KB
|
34
|
+
# 396 leaks for 10464 total leaked bytes.
|
35
|
+
|
36
|
+
|
28
37
|
GCAttributes = [:processed, :live, :freelist, :freed, :time]
|
29
38
|
GCSummaries = [:min, :max, :mean, :stddev, :stddev_percentage]
|
30
39
|
|
@@ -41,7 +50,8 @@ class GCInfo
|
|
41
50
|
|
42
51
|
attr_reader(*GCAttributes)
|
43
52
|
attr_reader :entries, :num_requests, :collections, :garbage_produced, :time_total, :topology
|
44
|
-
attr_reader :live_objects, :freed_objects, :object_types
|
53
|
+
attr_reader :live_objects, :freed_objects, :object_types, :garbage_totals
|
54
|
+
attr_reader :mallocs, :malloced, :leaks, :leaked
|
45
55
|
|
46
56
|
GCAttributes.each do |attr|
|
47
57
|
GCSummaries.each do |method|
|
@@ -54,6 +64,7 @@ class GCInfo
|
|
54
64
|
@num_requests = 0
|
55
65
|
@topology = []
|
56
66
|
@object_types = Set.new
|
67
|
+
@mallocs = @malloced = @leaks = @leaked = 0
|
57
68
|
|
58
69
|
file.each_line do |line|
|
59
70
|
case line
|
@@ -72,11 +83,18 @@ class GCInfo
|
|
72
83
|
when /^number of requests processed: (\d+)$/
|
73
84
|
@num_requests = $1.to_i
|
74
85
|
when /^HEAP\[\s*(\d+)\]: size=\s*(\d+)$/
|
86
|
+
@topology = [] if $1.to_i == 0
|
75
87
|
@topology << $2.to_i
|
76
88
|
when /^kept (\d+) \/ freed (\d+) objects of type ([a-zA-Z]+)/
|
77
89
|
@object_types.add($3)
|
78
90
|
@entries.last.live_objects[$3] = $1.to_i
|
79
91
|
@entries.last.freed_objects[$3] = $2.to_i
|
92
|
+
when /^(\d+) nodes malloced for (\d+) KB$/
|
93
|
+
@mallocs = $1.to_i
|
94
|
+
@malloced = $2.to_i * 1024
|
95
|
+
when /^(\d+) leaks for (\d+) total leaked bytes.$/
|
96
|
+
@leaks = $1.to_i
|
97
|
+
@leaked = $2.to_i
|
80
98
|
end
|
81
99
|
end
|
82
100
|
|
@@ -85,10 +103,18 @@ class GCInfo
|
|
85
103
|
@garbage_produced = @entries.map{|e| e.freed}.sum
|
86
104
|
@live_objects = @entries.map{|e| e.live_objects}
|
87
105
|
@freed_objects = @entries.map{|e| e.freed_objects}
|
106
|
+
@freelist = @entries.map{|e| e.freelist}
|
107
|
+
@garbage_totals = @freed_objects.inject(Hash.new(0)) do |totals, freed|
|
108
|
+
freed.each do |object_type, count|
|
109
|
+
totals[object_type] += freed[object_type] || 0
|
110
|
+
end
|
111
|
+
totals
|
112
|
+
end
|
88
113
|
|
89
114
|
GCAttributes.each do |attr|
|
90
115
|
a = @entries.map{|e| e.send attr}
|
91
|
-
|
116
|
+
# we need to pop the last entry, as the freelist is not empty when doing the last forced GC
|
117
|
+
a.pop if :freelist == attr.to_sym
|
92
118
|
|
93
119
|
[:min, :max, :mean].each do |method|
|
94
120
|
instance_variable_set "@#{attr}_#{method}", (a.send method)
|
@@ -99,6 +125,15 @@ class GCInfo
|
|
99
125
|
end
|
100
126
|
end
|
101
127
|
|
128
|
+
OBJECT_TYPES = %w(NODE STRING ARRAY HASH SCOPE VARMAP CLASS ICLASS REGEXP FLOAT MATCH FILE DATA MODULE OBJECT)
|
129
|
+
|
130
|
+
class << self
|
131
|
+
def object_types(list_of_gc_infos)
|
132
|
+
list_of_gc_infos.inject(OBJECT_TYPES) do |object_types, gci|
|
133
|
+
(object_types + gci.object_types.to_a).uniq
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
102
137
|
end
|
103
138
|
|
104
139
|
|
@@ -106,7 +141,7 @@ end
|
|
106
141
|
### mode:ruby ***
|
107
142
|
### End: ***
|
108
143
|
|
109
|
-
# Copyright (C) 2006, 2007 Stefan Kaes
|
144
|
+
# Copyright (C) 2006, 2007, 2008 Stefan Kaes
|
110
145
|
#
|
111
146
|
# This program is free software; you can redistribute it and/or modify
|
112
147
|
# it under the terms of the GNU General Public License as published by
|
data/lib/railsbench/perf_info.rb
CHANGED
@@ -129,7 +129,7 @@ end
|
|
129
129
|
### mode:ruby ***
|
130
130
|
### End: ***
|
131
131
|
|
132
|
-
# Copyright (C) 2006, 2007 Stefan Kaes
|
132
|
+
# Copyright (C) 2006, 2007, 2008 Stefan Kaes
|
133
133
|
#
|
134
134
|
# This program is free software; you can redistribute it and/or modify
|
135
135
|
# it under the terms of the GNU General Public License as published by
|
@@ -1,179 +1,202 @@
|
|
1
|
-
# some utility methods
|
2
|
-
|
3
|
-
class Array
|
4
|
-
def index_map
|
5
|
-
res = {}
|
6
|
-
each_with_index{|element, index| res[index] = element}
|
7
|
-
res
|
8
|
-
end
|
9
|
-
|
10
|
-
def restrict_to(index_set)
|
11
|
-
res = []
|
12
|
-
each_with_index{|e,i| res << e if index_set.include?(i)}
|
13
|
-
res
|
14
|
-
end
|
15
|
-
|
16
|
-
def sum
|
17
|
-
inject(0.0){|r,v| r += v }
|
18
|
-
end
|
19
|
-
|
20
|
-
def mean
|
21
|
-
sum/length
|
22
|
-
end
|
23
|
-
|
24
|
-
def stddev(mean=nil)
|
25
|
-
mean ||= self.mean
|
26
|
-
r = inject(0.0){|r,v| r += (v-mean)*(v-mean) }
|
27
|
-
Math.sqrt(r/(length-1))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def stddev_percentage(stddev, mean)
|
32
|
-
stddev.zero? ? 0.0 : (stddev/mean)*100
|
33
|
-
end
|
34
|
-
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
perf_runs.
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
print_cmd
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
#
|
177
|
-
|
178
|
-
|
179
|
-
|
1
|
+
# some utility methods
|
2
|
+
|
3
|
+
class Array
|
4
|
+
def index_map
|
5
|
+
res = {}
|
6
|
+
each_with_index{|element, index| res[index] = element}
|
7
|
+
res
|
8
|
+
end
|
9
|
+
|
10
|
+
def restrict_to(index_set)
|
11
|
+
res = []
|
12
|
+
each_with_index{|e,i| res << e if index_set.include?(i)}
|
13
|
+
res
|
14
|
+
end
|
15
|
+
|
16
|
+
def sum
|
17
|
+
inject(0.0){|r,v| r += v }
|
18
|
+
end
|
19
|
+
|
20
|
+
def mean
|
21
|
+
sum/length
|
22
|
+
end
|
23
|
+
|
24
|
+
def stddev(mean=nil)
|
25
|
+
mean ||= self.mean
|
26
|
+
r = inject(0.0){|r,v| r += (v-mean)*(v-mean) }
|
27
|
+
Math.sqrt(r/(length-1))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def stddev_percentage(stddev, mean)
|
32
|
+
stddev.zero? ? 0.0 : (stddev/mean)*100
|
33
|
+
end
|
34
|
+
|
35
|
+
def determine_rails_root_or_die!(msg=nil)
|
36
|
+
unless ENV['RAILS_ROOT']
|
37
|
+
if File.directory?("config") && File.exists?("config/environment.rb")
|
38
|
+
ENV['RAILS_ROOT'] = File.expand_path(".")
|
39
|
+
else
|
40
|
+
die(msg || "#{File.basename $PROGRAM_NAME}: $RAILS_ROOT not set and could not be configured automatically")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def die(msg, error_code=1)
|
46
|
+
$stderr.puts msg
|
47
|
+
exit error_code
|
48
|
+
end
|
49
|
+
|
50
|
+
class File
|
51
|
+
def self.open_or_die(filename, &block)
|
52
|
+
filename = filename.sub(/^\/([cdefgh])(\/)/, '\1:\2') if RUBY_PLATFORM =~ /win32/
|
53
|
+
begin
|
54
|
+
if stat(filename).readable?
|
55
|
+
open(filename, &block)
|
56
|
+
else
|
57
|
+
die "file #{filename} is unreadable"
|
58
|
+
end
|
59
|
+
rescue
|
60
|
+
die "file #{filename} does not exist"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def truncate(text, length = 32, truncate_string = "...")
|
66
|
+
if text.nil? then return "" end
|
67
|
+
l = truncate_string.length + 1
|
68
|
+
|
69
|
+
if RUBY_VERSION !~ /1.9/ && $KCODE == "NONE"
|
70
|
+
text.length > length ? text[0..(length - l)] + truncate_string : text
|
71
|
+
else
|
72
|
+
chars = text.split(//)
|
73
|
+
chars.length > length ? chars[0..(length - l)].join + truncate_string : text
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
RAILSBENCH_BINDIR = File.expand_path(File.dirname(__FILE__) + "/../../script")
|
78
|
+
|
79
|
+
def enable_gc_stats(file)
|
80
|
+
ENV['RUBY_GC_STATS'] = "1"
|
81
|
+
ENV['RUBY_GC_DATA_FILE'] = file
|
82
|
+
end
|
83
|
+
|
84
|
+
def disable_gc_stats
|
85
|
+
ENV.delete 'RUBY_GC_STATS'
|
86
|
+
ENV.delete 'RUBY_GC_DATA_FILE'
|
87
|
+
end
|
88
|
+
|
89
|
+
def unset_gc_variables
|
90
|
+
%w(RUBY_HEAP_MIN_SLOTS RUBY_GC_MALLOC_LIMIT RUBY_HEAP_FREE_MIN).each{|v| ENV.delete v}
|
91
|
+
end
|
92
|
+
|
93
|
+
def load_gc_variables(gc_spec)
|
94
|
+
File.open_or_die("#{ENV['RAILS_ROOT']}/config/#{gc_spec}.gc").each_line do |line|
|
95
|
+
ENV[$1] = $2 if line =~ /^(?:export )?(.*)=(.*)$/
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_gc_variables(argv)
|
100
|
+
gc_spec = nil
|
101
|
+
argv.each{|arg| gc_spec=$1 if arg =~ /-gc=([^ ]*)/}
|
102
|
+
|
103
|
+
if gc_spec
|
104
|
+
load_gc_variables(gc_spec)
|
105
|
+
else
|
106
|
+
unset_gc_variables
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def benchmark_file_name(benchmark, config_name, prefix=nil, suffix=nil)
|
111
|
+
perf_data_dir = (ENV['RAILS_PERF_DATA'] ||= ENV['HOME'])
|
112
|
+
date = Time.now.strftime '%m-%d'
|
113
|
+
suffix = ".#{suffix}" if suffix
|
114
|
+
ENV['RAILS_BENCHMARK_FILE'] =
|
115
|
+
if config_name
|
116
|
+
"#{perf_data_dir}/#{date}.#{benchmark}.#{config_name}#{suffix}.txt"
|
117
|
+
else
|
118
|
+
"#{perf_data_dir}/perf_run#{prefix}.#{benchmark}#{suffix}.txt"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def quote_arguments(argv)
|
123
|
+
argv.map{|a| a.include?(' ') ? "'#{a}'" : a.to_s}.join(' ')
|
124
|
+
end
|
125
|
+
|
126
|
+
def ruby
|
127
|
+
ENV['RUBY'] || "ruby"
|
128
|
+
end
|
129
|
+
|
130
|
+
def perf_run(script, iterations, options, raw_data_file)
|
131
|
+
perf_runs = (ENV['RAILS_PERF_RUNS'] ||= "3").to_i
|
132
|
+
|
133
|
+
disable_gc_stats
|
134
|
+
set_gc_variables([iterations, options])
|
135
|
+
|
136
|
+
perf_options = "#{iterations} #{options}"
|
137
|
+
null = (RUBY_PLATFORM =~ /win32/i) ? 'nul' : '/dev/null'
|
138
|
+
|
139
|
+
perf_cmd = "#{ruby} #{RAILSBENCH_BINDIR}/perf_bench #{perf_options}"
|
140
|
+
print_cmd = "#{ruby} #{RAILSBENCH_BINDIR}/perf_times #{raw_data_file}"
|
141
|
+
|
142
|
+
puts "benchmarking #{perf_runs} runs with options #{perf_options}"
|
143
|
+
|
144
|
+
File.open(raw_data_file, "w"){ |f| f.puts perf_cmd }
|
145
|
+
perf_runs.times do
|
146
|
+
system("#{perf_cmd} >#{null}") || die("#{script}: #{perf_cmd} returned #{$?}")
|
147
|
+
end
|
148
|
+
File.open(raw_data_file, "a" ){|f| f.puts }
|
149
|
+
|
150
|
+
unset_gc_variables
|
151
|
+
system(print_cmd) || die("#{script}: #{print_cmd} returned #{$?}")
|
152
|
+
end
|
153
|
+
|
154
|
+
def perf_run_gc(script, iterations, options, raw_data_file)
|
155
|
+
warmup = "-warmup"
|
156
|
+
warmup = "" if options =~ /-warmup/
|
157
|
+
|
158
|
+
enable_gc_stats(raw_data_file)
|
159
|
+
set_gc_variables([options])
|
160
|
+
|
161
|
+
perf_options = "#{iterations} #{warmup} #{options}"
|
162
|
+
null = (RUBY_PLATFORM =~ /win32/) ? 'nul' : '/dev/null'
|
163
|
+
|
164
|
+
perf_cmd = "#{ruby} #{RAILSBENCH_BINDIR}/run_urls #{perf_options} >#{null}"
|
165
|
+
print_cmd = "#{ruby} #{RAILSBENCH_BINDIR}/perf_times_gc #{raw_data_file}"
|
166
|
+
|
167
|
+
if options =~ /-leaks/
|
168
|
+
if RUBY_PLATFORM =~ /darwin9/
|
169
|
+
puts "enabling MallocStackLogging"
|
170
|
+
perf_cmd.insert(0, "MallocStackLogging=1 ")
|
171
|
+
else
|
172
|
+
die "leak debugging not supported on #{RUBY_PLATFORM}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
puts "benchmarking GC performance with options #{perf_options}"
|
177
|
+
puts
|
178
|
+
|
179
|
+
system(perf_cmd) || die("#{script}: #{perf_cmd} returned #{$?}")
|
180
|
+
|
181
|
+
disable_gc_stats
|
182
|
+
unset_gc_variables
|
183
|
+
system(print_cmd) || die("#{script}: #{print_cmd} returned #{$?}")
|
184
|
+
end
|
185
|
+
|
186
|
+
__END__
|
187
|
+
|
188
|
+
# Copyright (C) 2005-2008 Stefan Kaes
|
189
|
+
#
|
190
|
+
# This program is free software; you can redistribute it and/or modify
|
191
|
+
# it under the terms of the GNU General Public License as published by
|
192
|
+
# the Free Software Foundation; either version 2 of the License, or
|
193
|
+
# (at your option) any later version.
|
194
|
+
#
|
195
|
+
# This program is distributed in the hope that it will be useful,
|
196
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
197
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
198
|
+
# GNU General Public License for more details.
|
199
|
+
#
|
200
|
+
# You should have received a copy of the GNU General Public License
|
201
|
+
# along with this program; if not, write to the Free Software
|
202
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|