ruby-prof 0.11.2-x86-mingw32 → 0.12.1-x86-mingw32
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/CHANGES +27 -0
- data/README.rdoc +15 -15
- data/Rakefile +5 -0
- data/bin/ruby-prof +274 -265
- data/ext/ruby_prof/rp_call_info.c +33 -24
- data/ext/ruby_prof/rp_call_info.h +2 -1
- data/ext/ruby_prof/rp_measure.c +1 -1
- data/ext/ruby_prof/rp_measure.h +1 -1
- data/ext/ruby_prof/rp_measure_allocations.c +1 -1
- data/ext/ruby_prof/rp_measure_cpu_time.c +1 -1
- data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
- data/ext/ruby_prof/rp_measure_gc_time.c +1 -1
- data/ext/ruby_prof/rp_measure_memory.c +1 -1
- data/ext/ruby_prof/rp_measure_process_time.c +2 -2
- data/ext/ruby_prof/rp_measure_wall_time.c +2 -2
- data/ext/ruby_prof/rp_method.c +11 -24
- data/ext/ruby_prof/rp_method.h +2 -3
- data/ext/ruby_prof/rp_stack.c +55 -14
- data/ext/ruby_prof/rp_stack.h +10 -10
- data/ext/ruby_prof/rp_thread.c +30 -21
- data/ext/ruby_prof/rp_thread.h +3 -3
- data/ext/ruby_prof/ruby_prof.c +9 -88
- data/ext/ruby_prof/ruby_prof.h +1 -1
- data/ext/ruby_prof/vc/ruby_prof.sln +12 -6
- data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +2 -0
- data/ext/ruby_prof/vc/{ruby_prof.vcxproj → ruby_prof_19.vcxproj} +4 -1
- data/ext/ruby_prof/vc/ruby_prof_20.vcxproj +112 -0
- data/ext/ruby_prof/version.h +4 -4
- data/lib/1.8/ruby_prof.so +0 -0
- data/lib/1.9/ruby_prof.so +0 -0
- data/lib/2.0/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +1 -0
- data/lib/ruby-prof/call_info.rb +1 -1
- data/lib/ruby-prof/call_info_visitor.rb +4 -2
- data/lib/ruby-prof/compatibility.rb +13 -3
- data/lib/ruby-prof/method_info.rb +1 -1
- data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
- data/lib/ruby-prof/printers/call_stack_printer.rb +3 -3
- data/lib/ruby-prof/printers/dot_printer.rb +2 -2
- data/lib/ruby-prof/printers/flat_printer.rb +4 -4
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +2 -2
- data/lib/ruby-prof/printers/graph_html_printer.rb +3 -4
- data/lib/ruby-prof/printers/graph_printer.rb +15 -15
- data/lib/ruby-prof/profile.rb +1 -1
- data/lib/ruby-prof/rack.rb +0 -5
- data/lib/ruby-prof/thread.rb +22 -0
- data/ruby-prof.gemspec +2 -1
- data/test/basic_test.rb +77 -45
- data/test/call_info_test.rb +78 -0
- data/test/call_info_visitor_test.rb +1 -1
- data/test/dynamic_method_test.rb +14 -8
- data/test/measure_cpu_time_test.rb +23 -12
- data/test/measure_process_time_test.rb +21 -170
- data/test/measure_wall_time_test.rb +59 -13
- data/test/method_elimination_test.rb +30 -19
- data/test/pause_resume_test.rb +129 -22
- data/test/prime.rb +1 -2
- data/test/printers_test.rb +8 -17
- data/test/recursive_test.rb +6 -50
- data/test/test_helper.rb +30 -10
- data/test/test_suite.rb +1 -2
- metadata +23 -7
- data/test/bug_test.rb +0 -6
- data/test/gc_test.rb +0 -35
- data/test/pause_test.rb +0 -57
- data/test/prime_test.rb +0 -13
data/CHANGES
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
0.12.1 (2013-01-19)
|
2
|
+
======================
|
3
|
+
* Add back in pause/resume support since Rails uses it
|
4
|
+
|
5
|
+
0.12.0 (2013-01-06)
|
6
|
+
======================
|
7
|
+
* Ruby 2.0.0 support (Charlie Savage)
|
8
|
+
* Fix issue where profiling results could exceed 100% if profile code had multiple top level methods (Charlie Savage)
|
9
|
+
* Replaced RubyProf::Thread#top_method with RubyProf::Thread#top_methods (Charlie Savage)
|
10
|
+
* Added RubyProf::Thread#total_time (Charlie Savage)
|
11
|
+
* Remove the -r and -e command line options. If you need specific libraries or code profiled then add them
|
12
|
+
to your code (Charlie Savage).
|
13
|
+
* Rewrite ruby-prof script to be more self-contained (Gary Weaver)
|
14
|
+
* Fix list formatting in readme (Thilo Rusche)
|
15
|
+
* Remove pause/resume support since its buggy and complicates the code
|
16
|
+
|
17
|
+
0.11.3 (2012-12-27)
|
18
|
+
======================
|
19
|
+
* Prefix c functions with prof_ to avoid name conflicts (Kenta Murata)
|
20
|
+
* Update ruby-prof script to avoid seg faults (Gary Weaver)
|
21
|
+
* Rakefile updates (Roger Pack)
|
22
|
+
* Fix regexp file reading (Gilbert Roulot)
|
23
|
+
* Update documentation (Timo Schilling)
|
24
|
+
* Fix up ruby warnings (Mike Gehard)
|
25
|
+
* Remove duplicate code (Chas Lemley)
|
26
|
+
|
27
|
+
|
1
28
|
0.11.2 (2012-05-06)
|
2
29
|
======================
|
3
30
|
* Fix compile issue with BOOL. Should be _Bool for C99.
|
data/README.rdoc
CHANGED
@@ -15,7 +15,7 @@ ruby-prof is a fast code profiler for Ruby. Its features include:
|
|
15
15
|
|
16
16
|
== Requirements
|
17
17
|
|
18
|
-
ruby-prof requires Ruby 1.8.7 or 1.9.
|
18
|
+
ruby-prof requires Ruby 1.8.7 or 1.9.2 and higher.
|
19
19
|
|
20
20
|
If you are running Linux or Unix you'll need a C compiler so the extension
|
21
21
|
can be compiled when it is installed.
|
@@ -186,29 +186,29 @@ profile.rb.
|
|
186
186
|
So to profile Rails:
|
187
187
|
|
188
188
|
1. Create a new profile.rb environment. Make sure to turn on cache_classes
|
189
|
-
and cache_template_loading. Otherwise your profiling results will be
|
190
|
-
overwhelemed by the time Rails spends loading required files. You should
|
191
|
-
likely turn off caching.
|
189
|
+
and cache_template_loading. Otherwise your profiling results will be
|
190
|
+
overwhelemed by the time Rails spends loading required files. You should
|
191
|
+
likely turn off caching.
|
192
192
|
|
193
193
|
2. Add the ruby-prof to your gemfile:
|
194
194
|
|
195
|
-
|
196
|
-
|
197
|
-
|
195
|
+
group :profile do
|
196
|
+
gem 'ruby-prof'
|
197
|
+
end
|
198
198
|
|
199
199
|
3. Add the ruby prof rack adapter to your middleware stack. One way to
|
200
|
-
do this is by adding the following code to config.ru:
|
200
|
+
do this is by adding the following code to config.ru:
|
201
201
|
|
202
|
-
|
203
|
-
|
204
|
-
|
202
|
+
if Rails.env.profile?
|
203
|
+
use Rack::RubyProf, :path => '/temp/profile'
|
204
|
+
end
|
205
205
|
|
206
|
-
The path is where you want profiling results to be stored. By default the
|
207
|
-
rack adapter will generate a html call graph report and flat text report.
|
206
|
+
The path is where you want profiling results to be stored. By default the
|
207
|
+
rack adapter will generate a html call graph report and flat text report.
|
208
208
|
|
209
209
|
4. Now make a request to your running server. New profiling information will
|
210
|
-
be generated for each request. Note that each request will overwrite
|
211
|
-
the profiling reports created by the previous request!
|
210
|
+
be generated for each request. Note that each request will overwrite
|
211
|
+
the profiling reports created by the previous request!
|
212
212
|
|
213
213
|
== Reports
|
214
214
|
|
data/Rakefile
CHANGED
@@ -5,6 +5,7 @@ require "rake/extensiontask"
|
|
5
5
|
require "rake/testtask"
|
6
6
|
require "rdoc/task"
|
7
7
|
require "date"
|
8
|
+
require 'rake/clean'
|
8
9
|
|
9
10
|
# To release a version of ruby-prof:
|
10
11
|
# * Update version.h
|
@@ -78,6 +79,10 @@ end
|
|
78
79
|
|
79
80
|
task :default => :package
|
80
81
|
|
82
|
+
for file in Dir['**/*.so']
|
83
|
+
CLEAN.include file
|
84
|
+
end
|
85
|
+
|
81
86
|
desc 'Run the ruby-prof test suite'
|
82
87
|
Rake::TestTask.new do |t|
|
83
88
|
t.libs += %w(lib ext test)
|
data/bin/ruby-prof
CHANGED
@@ -13,308 +13,317 @@
|
|
13
13
|
#
|
14
14
|
# See also the readme "reports" section for the various outputs
|
15
15
|
|
16
|
+
# First require ruby-prof
|
17
|
+
require 'rubygems'
|
18
|
+
require 'ruby-prof'
|
19
|
+
|
20
|
+
# Now setup option parser
|
16
21
|
require 'ostruct'
|
17
22
|
require 'optparse'
|
18
|
-
require File.expand_path('../../lib/ruby-prof', __FILE__)
|
19
|
-
|
20
|
-
options = OpenStruct.new
|
21
|
-
options.measure_mode = RubyProf::PROCESS_TIME
|
22
|
-
options.printer = RubyProf::FlatPrinter
|
23
|
-
options.min_percent = 0
|
24
|
-
options.file = nil
|
25
|
-
options.replace_prog_name = false
|
26
|
-
options.specialized_instruction = false
|
27
|
-
|
28
|
-
opts = OptionParser.new do |opts|
|
29
|
-
opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
|
30
|
-
"Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
|
31
|
-
|
32
|
-
opts.separator ""
|
33
|
-
opts.separator "Options:"
|
34
|
-
|
35
|
-
|
36
|
-
opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot],
|
37
|
-
'Select a printer:',
|
38
|
-
' flat - Prints a flat profile as text (default).',
|
39
|
-
' flat_with_line_numbers - same as flat, with line numbers.',
|
40
|
-
' graph - Prints a graph profile as text.',
|
41
|
-
' graph_html - Prints a graph profile as html.',
|
42
|
-
' call_tree - format for KCacheGrind',
|
43
|
-
' call_stack - prints a HTML visualization of the call tree',
|
44
|
-
' dot - Prints a graph profile as a dot file'
|
45
|
-
) do |printer|
|
46
|
-
|
47
|
-
|
48
|
-
case printer
|
49
|
-
when :flat
|
50
|
-
options.printer = RubyProf::FlatPrinter
|
51
|
-
when :flat_with_line_numbers
|
52
|
-
options.printer = RubyProf::FlatPrinterWithLineNumbers
|
53
|
-
when :graph
|
54
|
-
options.printer = RubyProf::GraphPrinter
|
55
|
-
when :graph_html
|
56
|
-
options.printer = RubyProf::GraphHtmlPrinter
|
57
|
-
when :call_tree
|
58
|
-
options.printer = RubyProf::CallTreePrinter
|
59
|
-
when :call_stack
|
60
|
-
options.printer = RubyProf::CallStackPrinter
|
61
|
-
when :dot
|
62
|
-
options.printer = RubyProf::DotPrinter
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
opts.on('-m min_percent', '--min_percent=min_percent', Float,
|
67
|
-
'The minimum percent a method must take before ',
|
68
|
-
' being included in output reports.',
|
69
|
-
' this option is not supported for call tree.') do |min_percent|
|
70
|
-
options.min_percent = min_percent
|
71
|
-
end
|
72
23
|
|
73
|
-
|
74
|
-
|
75
|
-
options
|
76
|
-
options.old_wd = Dir.pwd
|
77
|
-
end
|
78
|
-
|
79
|
-
opts.on('--mode=measure_mode',
|
80
|
-
[:process, :wall, :cpu, :allocations, :memory, :gc_runs, :gc_time],
|
81
|
-
'Select what ruby-prof should measure:',
|
82
|
-
' process - Process time (default).',
|
83
|
-
' wall - Wall time.',
|
84
|
-
' cpu - CPU time (Pentium and PowerPCs only).',
|
85
|
-
' allocations - Object allocations (requires patched Ruby interpreter).',
|
86
|
-
' memory - Allocated memory in KB (requires patched Ruby interpreter).',
|
87
|
-
' gc_runs - Number of garbage collections (requires patched Ruby interpreter).',
|
88
|
-
' gc_time - Time spent in garbage collection (requires patched Ruby interpreter).') do |measure_mode|
|
89
|
-
|
90
|
-
case measure_mode
|
91
|
-
when :process
|
92
|
-
options.measure_mode = RubyProf::PROCESS_TIME
|
93
|
-
when :wall
|
94
|
-
options.measure_mode = RubyProf::WALL_TIME
|
95
|
-
when :cpu
|
96
|
-
options.measure_mode = RubyProf::CPU_TIME
|
97
|
-
when :allocations
|
98
|
-
options.measure_mode = RubyProf::ALLOCATIONS
|
99
|
-
when :memory
|
100
|
-
options.measure_mode = RubyProf::MEMORY
|
101
|
-
when :gc_runs
|
102
|
-
options.measure_mode = RubyProf::GC_RUNS
|
103
|
-
when :gc_time
|
104
|
-
options.measure_mode = RubyProf::GC_TIME
|
105
|
-
end
|
106
|
-
end
|
24
|
+
module RubyProf
|
25
|
+
class Cmd
|
26
|
+
attr_accessor :options
|
107
27
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
' self - Self time',
|
112
|
-
' wait - Wait time',
|
113
|
-
' child - Child time') do |sort_mode|
|
114
|
-
|
115
|
-
options.sort_method = case sort_mode
|
116
|
-
when :total
|
117
|
-
:total_time
|
118
|
-
when :self
|
119
|
-
:self_time
|
120
|
-
when :wait
|
121
|
-
:wait_time
|
122
|
-
when :child
|
123
|
-
:children_time
|
124
|
-
end
|
125
|
-
end
|
28
|
+
def initialize
|
29
|
+
setup_options
|
30
|
+
parse_args
|
126
31
|
|
127
|
-
|
32
|
+
load_pre_libs
|
33
|
+
load_pre_execs
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_options
|
37
|
+
@options = OpenStruct.new
|
38
|
+
options.measure_mode = RubyProf::PROCESS_TIME
|
39
|
+
options.printer = RubyProf::FlatPrinter
|
40
|
+
options.min_percent = 0
|
41
|
+
options.file = nil
|
42
|
+
options.replace_prog_name = false
|
43
|
+
options.specialized_instruction = false
|
44
|
+
|
45
|
+
options.pre_libs = Array.new
|
46
|
+
options.pre_execs = Array.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def option_parser
|
50
|
+
OptionParser.new do |opts|
|
51
|
+
opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
|
52
|
+
"Usage: ruby-prof [options] <script.rb> [--] [profiled-script-command-line-options]"
|
53
|
+
|
54
|
+
opts.separator ""
|
55
|
+
opts.separator "Options:"
|
56
|
+
|
57
|
+
opts.on('-p printer', '--printer=printer', [:flat, :flat_with_line_numbers, :graph, :graph_html, :call_tree, :call_stack, :dot],
|
58
|
+
'Select a printer:',
|
59
|
+
' flat - Prints a flat profile as text (default).',
|
60
|
+
' flat_with_line_numbers - same as flat, with line numbers.',
|
61
|
+
' graph - Prints a graph profile as text.',
|
62
|
+
' graph_html - Prints a graph profile as html.',
|
63
|
+
' call_tree - format for KCacheGrind',
|
64
|
+
' call_stack - prints a HTML visualization of the call tree',
|
65
|
+
' dot - Prints a graph profile as a dot file'
|
66
|
+
) do |printer|
|
67
|
+
|
68
|
+
|
69
|
+
case printer
|
70
|
+
when :flat
|
71
|
+
options.printer = RubyProf::FlatPrinter
|
72
|
+
when :flat_with_line_numbers
|
73
|
+
options.printer = RubyProf::FlatPrinterWithLineNumbers
|
74
|
+
when :graph
|
75
|
+
options.printer = RubyProf::GraphPrinter
|
76
|
+
when :graph_html
|
77
|
+
options.printer = RubyProf::GraphHtmlPrinter
|
78
|
+
when :call_tree
|
79
|
+
options.printer = RubyProf::CallTreePrinter
|
80
|
+
when :call_stack
|
81
|
+
options.printer = RubyProf::CallStackPrinter
|
82
|
+
when :dot
|
83
|
+
options.printer = RubyProf::DotPrinter
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.on('-m min_percent', '--min_percent=min_percent', Float,
|
88
|
+
'The minimum percent a method must take before ',
|
89
|
+
' being included in output reports.',
|
90
|
+
' this option is not supported for call tree.') do |min_percent|
|
91
|
+
options.min_percent = min_percent
|
92
|
+
end
|
93
|
+
|
94
|
+
opts.on('-f path', '--file=path',
|
95
|
+
'Output results to a file instead of standard out.') do |file|
|
96
|
+
options.file = file
|
97
|
+
options.old_wd = Dir.pwd
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on('--mode=measure_mode',
|
101
|
+
[:process, :wall, :cpu, :allocations, :memory, :gc_runs, :gc_time],
|
102
|
+
'Select what ruby-prof should measure:',
|
103
|
+
' process - Process time (default).',
|
104
|
+
' wall - Wall time.',
|
105
|
+
' cpu - CPU time (Pentium and PowerPCs only).',
|
106
|
+
' allocations - Object allocations (requires patched Ruby interpreter).',
|
107
|
+
' memory - Allocated memory in KB (requires patched Ruby interpreter).',
|
108
|
+
' gc_runs - Number of garbage collections (requires patched Ruby interpreter).',
|
109
|
+
' gc_time - Time spent in garbage collection (requires patched Ruby interpreter).') do |measure_mode|
|
110
|
+
|
111
|
+
case measure_mode
|
112
|
+
when :process
|
113
|
+
options.measure_mode = RubyProf::PROCESS_TIME
|
114
|
+
when :wall
|
115
|
+
options.measure_mode = RubyProf::WALL_TIME
|
116
|
+
when :cpu
|
117
|
+
options.measure_mode = RubyProf::CPU_TIME
|
118
|
+
when :allocations
|
119
|
+
options.measure_mode = RubyProf::ALLOCATIONS
|
120
|
+
when :memory
|
121
|
+
options.measure_mode = RubyProf::MEMORY
|
122
|
+
when :gc_runs
|
123
|
+
options.measure_mode = RubyProf::GC_RUNS
|
124
|
+
when :gc_time
|
125
|
+
options.measure_mode = RubyProf::GC_TIME
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
opts.on('-s sort_mode', '--sort=sort_mode', [:total, :self, :wait, :child],
|
130
|
+
'Select how ruby-prof results should be sorted:',
|
131
|
+
' total - Total time',
|
132
|
+
' self - Self time',
|
133
|
+
' wait - Wait time',
|
134
|
+
' child - Child time') do |sort_mode|
|
135
|
+
|
136
|
+
options.sort_method = case sort_mode
|
137
|
+
when :total
|
138
|
+
:total_time
|
139
|
+
when :self
|
140
|
+
:self_time
|
141
|
+
when :wait
|
142
|
+
:wait_time
|
143
|
+
when :child
|
144
|
+
:children_time
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
|
128
149
|
options.replace_prog_name = true
|
129
|
-
|
150
|
+
end
|
130
151
|
|
131
|
-
|
132
|
-
|
152
|
+
if defined?(VM)
|
153
|
+
opts.on("--specialized-instruction", "Turn on specified instruction.") do
|
133
154
|
options.specialized_instruction = true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
opts.on_tail("-h", "--help", "Show help message") do
|
159
|
+
puts opts
|
160
|
+
exit
|
161
|
+
end
|
162
|
+
|
163
|
+
opts.on_tail("--version", "Show version #{RubyProf::VERSION}") do
|
164
|
+
puts "ruby_prof " + RubyProf::VERSION
|
165
|
+
exit
|
166
|
+
end
|
167
|
+
|
168
|
+
opts.on("-v","Show version, set $VERBOSE to true, profile script if option given") do
|
169
|
+
puts "ruby version: " + [RUBY_PATCHLEVEL, RUBY_PLATFORM, RUBY_VERSION].join(' ')
|
170
|
+
$VERBOSE = true
|
171
|
+
end
|
172
|
+
|
173
|
+
opts.on("-d", "Set $DEBUG to true") do
|
174
|
+
$DEBUG = true
|
175
|
+
end
|
176
|
+
|
177
|
+
opts.on('-R lib', '--require-noprof lib', 'require a specific library (not profiled)') do |lib|
|
178
|
+
options.pre_libs << lib
|
179
|
+
end
|
180
|
+
|
181
|
+
opts.on('-E code', '--eval-noprof code', 'execute the ruby statements (not profiled)') do |code|
|
182
|
+
options.pre_execs << code
|
183
|
+
end
|
184
|
+
|
185
|
+
opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do|meth|
|
186
|
+
options.eliminate_methods ||= []
|
187
|
+
options.eliminate_methods << Regexp.new(meth)
|
188
|
+
end
|
189
|
+
|
190
|
+
opts.on('-X file', '--exclude-file file', 'exclude methods by regexp listed in file (see method elimination)') do|file|
|
191
|
+
options.eliminate_methods_files ||= []
|
192
|
+
options.eliminate_methods_files << file
|
193
|
+
end
|
194
|
+
|
195
|
+
opts.on('--exclude-common-cycles', 'make common iterators like Integer#times appear inlined') do |meth|
|
196
|
+
options.eliminate_methods ||= []
|
197
|
+
options.eliminate_methods += %w{
|
198
|
+
Integer#times
|
199
|
+
Integer#upto
|
200
|
+
Integer#downto
|
201
|
+
Enumerator#each
|
202
|
+
Enumerator#each_with_index
|
203
|
+
Enumerator#each_with_object
|
204
|
+
|
205
|
+
Array#each
|
206
|
+
Array#each_index
|
207
|
+
Array#reverse_each
|
208
|
+
Array#map
|
209
|
+
|
210
|
+
Hash#each
|
211
|
+
Hash#each_pair
|
212
|
+
Hash#each_key
|
213
|
+
Hash#each_value
|
214
|
+
|
215
|
+
Range#each
|
216
|
+
Enumerable#each_cons
|
217
|
+
Enumerable#each_entry
|
218
|
+
Enumerable#each_slice
|
219
|
+
Enumerable#each_with_index
|
220
|
+
Enumerable#each_with_object
|
221
|
+
Enumerable#reverse_each
|
222
|
+
Enumerable#inject
|
223
|
+
Enumerable#collect
|
224
|
+
Enumerable#reduce
|
225
|
+
}
|
226
|
+
#TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
|
227
|
+
end
|
228
|
+
|
229
|
+
opts.on('--exclude-common-callbacks', 'make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph') do|meth|
|
230
|
+
options.eliminate_methods ||= []
|
231
|
+
options.eliminate_methods += %w{
|
232
|
+
Method#call
|
233
|
+
Proc#call
|
234
|
+
ActiveSupport::Callbacks::ClassMethods#__run_callback
|
235
|
+
}
|
236
|
+
end
|
237
|
+
end
|
134
238
|
end
|
135
|
-
end
|
136
|
-
|
137
|
-
opts.on_tail("-h", "--help", "Show help message") do
|
138
|
-
puts opts
|
139
|
-
exit
|
140
|
-
end
|
141
|
-
|
142
|
-
opts.on_tail("--version", "Show version #{RubyProf::VERSION}") do
|
143
|
-
puts "ruby_prof " + RubyProf::VERSION
|
144
|
-
exit
|
145
|
-
end
|
146
|
-
|
147
|
-
opts.on("-v","Show version, set $VERBOSE to true, profile script if option given") do
|
148
|
-
puts "ruby version: " + [RUBY_PATCHLEVEL, RUBY_PLATFORM, RUBY_VERSION].join(' ')
|
149
|
-
$VERBOSE = true
|
150
|
-
end
|
151
|
-
|
152
|
-
opts.on("-d", "Set $DEBUG to true") do
|
153
|
-
$DEBUG = true
|
154
|
-
end
|
155
|
-
|
156
|
-
opts.on('-R lib', '--require-noprof lib', 'require a specific library (not profiled)') do |lib|
|
157
|
-
options.pre_libs ||= []
|
158
|
-
options.pre_libs << lib
|
159
|
-
end
|
160
239
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
240
|
+
def parse_args
|
241
|
+
# Make sure the user specified at least one file
|
242
|
+
if ARGV.length < 1 and not options.exec
|
243
|
+
puts opts
|
244
|
+
puts ""
|
245
|
+
puts "Must specify a script to run"
|
246
|
+
exit(-1)
|
247
|
+
end
|
165
248
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
249
|
+
self.option_parser.parse! ARGV
|
250
|
+
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
|
251
|
+
puts opts
|
252
|
+
puts e.message
|
253
|
+
exit(-1)
|
254
|
+
end
|
170
255
|
|
171
|
-
|
172
|
-
options.
|
173
|
-
|
174
|
-
|
256
|
+
def load_pre_libs
|
257
|
+
options.pre_libs.each do |lib|
|
258
|
+
require lib
|
259
|
+
end
|
260
|
+
end
|
175
261
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
262
|
+
def load_pre_execs
|
263
|
+
options.pre_execs.each do |exec|
|
264
|
+
eval(exec)
|
265
|
+
end
|
266
|
+
end
|
180
267
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
268
|
+
def run
|
269
|
+
# Get the script we will execute
|
270
|
+
script = ARGV.shift
|
271
|
+
if options.replace_prog_name
|
272
|
+
$0 = File.expand_path(script)
|
273
|
+
end
|
185
274
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
Enumerator#each_with_index
|
194
|
-
Enumerator#each_with_object
|
195
|
-
|
196
|
-
Array#each
|
197
|
-
Array#each_index
|
198
|
-
Array#reverse_each
|
199
|
-
Array#map
|
200
|
-
|
201
|
-
Hash#each
|
202
|
-
Hash#each_pair
|
203
|
-
Hash#each_key
|
204
|
-
Hash#each_value
|
205
|
-
|
206
|
-
Range#each
|
207
|
-
Enumerable#each_cons
|
208
|
-
Enumerable#each_entry
|
209
|
-
Enumerable#each_slice
|
210
|
-
Enumerable#each_with_index
|
211
|
-
Enumerable#each_with_object
|
212
|
-
Enumerable#reverse_each
|
213
|
-
Enumerable#inject
|
214
|
-
Enumerable#collect
|
215
|
-
Enumerable#reduce
|
216
|
-
}
|
217
|
-
#TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
|
218
|
-
end
|
275
|
+
# Set VM compile option
|
276
|
+
if defined?(VM)
|
277
|
+
VM::InstructionSequence.compile_option = {
|
278
|
+
:trace_instruction => true,
|
279
|
+
:specialized_instruction => options.specialized_instruction
|
280
|
+
}
|
281
|
+
end
|
219
282
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
Proc#call
|
225
|
-
ActiveSupport::Callbacks::ClassMethods#__run_callback
|
226
|
-
}
|
283
|
+
# Set the measure mode
|
284
|
+
RubyProf.measure_mode = options.measure_mode
|
285
|
+
RubyProf.start_script(script)
|
286
|
+
end
|
227
287
|
end
|
228
288
|
end
|
229
289
|
|
230
|
-
|
231
|
-
|
232
|
-
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument,
|
233
|
-
OptionParser::MissingArgument => e
|
234
|
-
puts opts
|
235
|
-
puts
|
236
|
-
puts e.message
|
237
|
-
exit(-1)
|
238
|
-
end
|
239
|
-
|
240
|
-
# Make sure the user specified at least one file
|
241
|
-
if ARGV.length < 1 and not options.exec
|
242
|
-
puts opts
|
243
|
-
puts ""
|
244
|
-
puts "Must specify a script to run"
|
245
|
-
exit(-1)
|
246
|
-
end
|
247
|
-
|
290
|
+
# Parse command line options
|
291
|
+
cmd = RubyProf::Cmd.new
|
248
292
|
|
249
|
-
# Install at_exit handler. It is important that we do this
|
293
|
+
# Install at_exit handler. It is important that we do this
|
250
294
|
# before loading the scripts so our at_exit handler run
|
251
|
-
# *after* any other one that will be installed.
|
295
|
+
# *after* any other one that will be installed.
|
252
296
|
|
253
297
|
at_exit {
|
254
298
|
# Stop profiling
|
255
299
|
result = RubyProf.stop
|
256
300
|
|
257
301
|
# Eliminate unwanted methods from call graph
|
258
|
-
|
259
|
-
|
302
|
+
if cmd.options.eliminate_methods
|
303
|
+
result.eliminate_methods!(cmd.options.eliminate_methods)
|
304
|
+
end
|
305
|
+
|
306
|
+
if cmd.options.eliminate_methods_files
|
307
|
+
cmd.options.eliminate_methods_files.each {|f| result.eliminate_methods!(f)}
|
308
|
+
end
|
260
309
|
|
261
310
|
# Create a printer
|
262
|
-
printer = options.printer.new(result)
|
263
|
-
printer_options = {:min_percent => options.min_percent, :sort_method => options.sort_method}
|
311
|
+
printer = cmd.options.printer.new(result)
|
312
|
+
printer_options = {:min_percent => cmd.options.min_percent, :sort_method => cmd.options.sort_method}
|
264
313
|
|
265
314
|
# Get output
|
266
|
-
if options.file
|
315
|
+
if cmd.options.file
|
267
316
|
# write it relative to the dir they *started* in, as it's a bit surprising to write it in the dir they end up in.
|
268
|
-
Dir.chdir(options.old_wd) do
|
269
|
-
File.open(options.file, 'w') do |file|
|
317
|
+
Dir.chdir(cmd.options.old_wd) do
|
318
|
+
File.open(cmd.options.file, 'w') do |file|
|
270
319
|
printer.print(file, printer_options)
|
271
320
|
end
|
272
321
|
end
|
273
322
|
else
|
274
|
-
# Print out results
|
323
|
+
# Print out results
|
275
324
|
printer.print(STDOUT, printer_options)
|
276
325
|
end
|
277
326
|
}
|
278
327
|
|
279
|
-
# Now
|
280
|
-
|
281
|
-
|
282
|
-
# Set VM compile option
|
283
|
-
if defined?(VM)
|
284
|
-
VM::InstructionSequence.compile_option = {
|
285
|
-
:trace_instruction => true,
|
286
|
-
:specialized_instruction => options.specialized_instruction
|
287
|
-
}
|
288
|
-
end
|
289
|
-
|
290
|
-
# Get the script we will execute
|
291
|
-
script = ARGV.shift
|
292
|
-
if options.replace_prog_name
|
293
|
-
$0 = File.expand_path(script)
|
294
|
-
end
|
295
|
-
|
296
|
-
if options.pre_libs
|
297
|
-
options.pre_libs.each { |l| require l }
|
298
|
-
end
|
299
|
-
|
300
|
-
if options.pre_exec
|
301
|
-
options.pre_exec.each { |c| eval c }
|
302
|
-
end
|
303
|
-
|
304
|
-
# do not pollute profiling report with OpenStruct#libs
|
305
|
-
ol = options.libs
|
306
|
-
oe = options.exec
|
307
|
-
|
308
|
-
# Start profiling
|
309
|
-
RubyProf.start
|
310
|
-
|
311
|
-
if ol
|
312
|
-
ol.each { |l| require l }
|
313
|
-
end
|
314
|
-
|
315
|
-
if oe
|
316
|
-
oe.each { |c| eval c }
|
317
|
-
end
|
318
|
-
|
319
|
-
# Load the script
|
320
|
-
load script if script
|
328
|
+
# Now profile some code
|
329
|
+
cmd.run
|