ruby-prof 1.7.1 → 1.7.2

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +8 -0
  3. data/ext/ruby_prof/extconf.rb +23 -22
  4. data/ext/ruby_prof/rp_call_trees.c +296 -296
  5. data/ext/ruby_prof/rp_call_trees.h +28 -28
  6. data/ext/ruby_prof/rp_measure_allocations.c +47 -47
  7. data/ext/ruby_prof/rp_measure_process_time.c +64 -66
  8. data/ext/ruby_prof/rp_measure_wall_time.c +52 -64
  9. data/ext/ruby_prof/rp_method.c +551 -551
  10. data/ext/ruby_prof/rp_stack.c +212 -212
  11. data/ext/ruby_prof/ruby_prof.c +50 -50
  12. data/ext/ruby_prof/ruby_prof.h +3 -2
  13. data/ext/ruby_prof/vc/ruby_prof.vcxproj +3 -3
  14. data/lib/ruby-prof/compatibility.rb +113 -113
  15. data/lib/ruby-prof/exclude_common_methods.rb +204 -204
  16. data/lib/ruby-prof/printers/abstract_printer.rb +156 -138
  17. data/lib/ruby-prof/version.rb +3 -3
  18. data/ruby-prof.gemspec +66 -65
  19. data/test/dynamic_method_test.rb +9 -21
  20. data/test/enumerable_test.rb +23 -21
  21. data/test/exclude_methods_test.rb +363 -257
  22. data/test/fiber_test.rb +195 -195
  23. data/test/gc_test.rb +104 -102
  24. data/test/line_number_test.rb +426 -289
  25. data/test/measure_allocations_test.rb +1172 -1081
  26. data/test/measure_memory_test.rb +1193 -1456
  27. data/test/measure_process_time_test.rb +3330 -2477
  28. data/test/measure_wall_time_test.rb +634 -568
  29. data/test/merge_test.rb +146 -146
  30. data/test/method_info_test.rb +100 -95
  31. data/test/printers_test.rb +178 -135
  32. data/test/recursive_test.rb +796 -622
  33. data/test/start_stop_test.rb +4 -4
  34. data/test/test_helper.rb +20 -20
  35. data/test/thread_test.rb +229 -231
  36. data/test/unique_call_path_test.rb +9 -22
  37. data/test/yarv_test.rb +1 -5
  38. metadata +19 -9
  39. data/test/crash2.rb +0 -144
@@ -1,138 +1,156 @@
1
- # encoding: utf-8
2
-
3
- module RubyProf
4
- # This is the base class for all Printers. It is never used directly.
5
- class AbstractPrinter
6
- # :stopdoc:
7
- def self.needs_dir?
8
- false
9
- end
10
- # :startdoc:
11
-
12
- # Create a new printer.
13
- #
14
- # result should be the output generated from a profiling run
15
- def initialize(result)
16
- @result = result
17
- @output = nil
18
- end
19
-
20
- # Returns the min_percent of time a method must take to be included in a profiling report
21
- def min_percent
22
- @options[:min_percent] || 0
23
- end
24
-
25
- # Returns the max_percent of time a method can take to be included in a profiling report
26
- def max_percent
27
- @options[:max_percent] || 100
28
- end
29
-
30
- # Returns the method to filter methods by (when using min_percent and max_percent)
31
- def filter_by
32
- @options[:filter_by] || :self_time
33
- end
34
-
35
- # Returns the time format used to show when a profile was run
36
- def time_format
37
- '%A, %B %-d at %l:%M:%S %p (%Z)'
38
- end
39
-
40
- # Returns how profile data should be sorted
41
- def sort_method
42
- @options[:sort_method]
43
- end
44
-
45
- # Prints a report to the provided output.
46
- #
47
- # output - Any IO object, including STDOUT or a file.
48
- # The default value is STDOUT.
49
- #
50
- # options - Hash of print options. Note that each printer can
51
- # define its own set of options.
52
- #
53
- # :min_percent - Number 0 to 100 that specifies the minimum
54
- # %self (the methods self time divided by the
55
- # overall total time) that a method must take
56
- # for it to be printed out in the report.
57
- # Default value is 0.
58
- #
59
- # :sort_method - Specifies method used for sorting method infos.
60
- # Available values are :total_time, :self_time,
61
- # :wait_time, :children_time
62
- # Default value is :total_time
63
- def print(output = STDOUT, options = {})
64
- @output = output
65
- setup_options(options)
66
- print_threads
67
- end
68
-
69
- # :nodoc:
70
- def setup_options(options = {})
71
- @options = options
72
- end
73
-
74
- def method_location(method)
75
- if method.source_file
76
- "#{method.source_file}:#{method.line}"
77
- end
78
- end
79
-
80
- def method_href(thread, method)
81
- h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
82
- end
83
-
84
- def open_asset(file)
85
- path = File.join(File.expand_path('../../assets', __FILE__), file)
86
- File.open(path, 'rb').read
87
- end
88
-
89
- def print_threads
90
- @result.threads.each do |thread|
91
- print_thread(thread)
92
- end
93
- end
94
-
95
- def print_thread(thread)
96
- print_header(thread)
97
- print_methods(thread)
98
- print_footer(thread)
99
- end
100
-
101
- def print_header(thread)
102
- @output << "Measure Mode: %s\n" % @result.measure_mode_string
103
- @output << "Thread ID: %d\n" % thread.id
104
- @output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
105
- @output << "Total: %0.6f\n" % thread.total_time
106
- @output << "Sort by: #{sort_method}\n"
107
- @output << "\n"
108
- print_column_headers
109
- end
110
-
111
- def print_column_headers
112
- end
113
-
114
- def print_footer(thread)
115
- @output << <<~EOT
116
-
117
- * recursively called methods
118
-
119
- Columns are:
120
-
121
- %self - The percentage of time spent in this method, derived from self_time/total_time.
122
- total - The time spent in this method and its children.
123
- self - The time spent in this method.
124
- wait - The amount of time this method waited for other threads.
125
- child - The time spent in this method's children.
126
- calls - The number of times this method was called.
127
- name - The name of the method.
128
- location - The location of the method.
129
-
130
- The interpretation of method names is:
131
-
132
- * MyObject#test - An instance method "test" of the class "MyObject"
133
- * <Object:MyObject>#test - The <> characters indicate a method on a singleton class.
134
-
135
- EOT
136
- end
137
- end
138
- end
1
+ # encoding: utf-8
2
+
3
+ module RubyProf
4
+ # This is the base class for all Printers. It is never used directly.
5
+ class AbstractPrinter
6
+ # :stopdoc:
7
+ def self.needs_dir?
8
+ false
9
+ end
10
+ # :startdoc:
11
+
12
+ # Create a new printer.
13
+ #
14
+ # result should be the output generated from a profiling run
15
+ def initialize(result)
16
+ @result = result
17
+ @output = nil
18
+ end
19
+
20
+ # Returns the min_percent of time a method must take to be included in a profiling report
21
+ def min_percent
22
+ @options[:min_percent] || 0
23
+ end
24
+
25
+ # Returns the max_percent of time a method can take to be included in a profiling report
26
+ def max_percent
27
+ @options[:max_percent] || 100
28
+ end
29
+
30
+ # Returns the method to filter methods by (when using min_percent and max_percent)
31
+ def filter_by
32
+ @options[:filter_by] || :self_time
33
+ end
34
+
35
+ # Returns the time format used to show when a profile was run
36
+ def time_format
37
+ '%A, %B %-d at %l:%M:%S %p (%Z)'
38
+ end
39
+
40
+ # Returns how profile data should be sorted
41
+ def sort_method
42
+ @options[:sort_method]
43
+ end
44
+
45
+ # Prints a report to the provided output.
46
+ #
47
+ # output - Any IO object, including STDOUT or a file.
48
+ # The default value is STDOUT.
49
+ #
50
+ # options - Hash of print options. Note that each printer can
51
+ # define its own set of options.
52
+ #
53
+ # :min_percent - Number 0 to 100 that specifies the minimum
54
+ # %self (the methods self time divided by the
55
+ # overall total time) that a method must take
56
+ # for it to be printed out in the report.
57
+ # Default value is 0.
58
+ #
59
+ # :sort_method - Specifies method used for sorting method infos.
60
+ # Available values are :total_time, :self_time,
61
+ # :wait_time, :children_time
62
+ # Default value is :total_time
63
+ def print(output = STDOUT, options = {})
64
+ @output = output
65
+ setup_options(options)
66
+ print_threads
67
+ end
68
+
69
+ # :nodoc:
70
+ def setup_options(options = {})
71
+ @options = options
72
+ end
73
+
74
+ def method_location(method)
75
+ if method.source_file
76
+ "#{method.source_file}:#{method.line}"
77
+ end
78
+ end
79
+
80
+ def method_href(thread, method)
81
+ h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + thread.fiber_id.to_s)
82
+ end
83
+
84
+ def open_asset(file)
85
+ path = File.join(File.expand_path('../../assets', __FILE__), file)
86
+ File.open(path, 'rb').read
87
+ end
88
+
89
+ def print_threads
90
+ @result.threads.each do |thread|
91
+ print_thread(thread)
92
+ end
93
+ end
94
+
95
+ def print_thread(thread)
96
+ print_header(thread)
97
+ print_methods(thread)
98
+ print_footer(thread)
99
+ end
100
+
101
+ def print_header(thread)
102
+ @output << "Measure Mode: %s\n" % @result.measure_mode_string
103
+ @output << "Thread ID: %d\n" % thread.id
104
+ @output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
105
+ @output << "Total: %0.6f\n" % thread.total_time
106
+ @output << "Sort by: #{sort_method}\n"
107
+ @output << "\n"
108
+ print_column_headers
109
+ end
110
+
111
+ def print_column_headers
112
+ end
113
+
114
+ def print_footer(thread)
115
+ metric_data = {
116
+ 0 => { label: "time", prefix: "", suffix: "spent" },
117
+ 1 => { label: "time", prefix: "", suffix: "spent" },
118
+ 2 => { label: "allocations", prefix: "number of ", suffix: "made" },
119
+ 3 => { label: "memory", prefix: "", suffix: "used" }
120
+ }
121
+
122
+ metric = metric_data[@result.measure_mode]
123
+
124
+ metric_label = metric[:label]
125
+ metric_suffix = metric[:suffix]
126
+ metric_prefix = metric[:prefix]
127
+
128
+ metric1 = "#{metric_label} #{metric_suffix}"
129
+ metric2 = "#{metric_prefix}#{metric1}"
130
+ metric3 = metric_label
131
+
132
+ # Output the formatted text
133
+ @output << <<~EOT
134
+
135
+ * recursively called methods
136
+
137
+ Columns are:
138
+
139
+ %self - The percentage of #{metric1} by this method relative to the total #{metric3} in the entire program.
140
+ total - The total #{metric2} by this method and its children.
141
+ self - The #{metric2} by this method.
142
+ wait - The time this method spent waiting for other threads.
143
+ child - The #{metric2} by this method's children.
144
+ calls - The number of times this method was called.
145
+ name - The name of the method.
146
+ location - The location of the method.
147
+
148
+ The interpretation of method names is:
149
+
150
+ * MyObject#test - An instance method "test" of the class "MyObject"
151
+ * <Object:MyObject>#test - The <> characters indicate a method on a singleton class.
152
+
153
+ EOT
154
+ end
155
+ end
156
+ end
@@ -1,3 +1,3 @@
1
- module RubyProf
2
- VERSION = "1.7.1"
3
- end
1
+ module RubyProf
2
+ VERSION = "1.7.2"
3
+ end
data/ruby-prof.gemspec CHANGED
@@ -1,65 +1,66 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- $:.push File.expand_path("../lib", __FILE__)
4
- require "ruby-prof/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "ruby-prof"
8
-
9
- spec.homepage = "https://github.com/ruby-prof/ruby-prof/"
10
- spec.summary = "Fast Ruby profiler"
11
- spec.description = <<-EOF
12
- ruby-prof is a fast code profiler for Ruby. It is a C extension and
13
- therefore is many times faster than the standard Ruby profiler. It
14
- supports both flat and graph profiles. For each method, graph profiles
15
- show how long the method ran, which methods called it and which
16
- methods it called. RubyProf generate both text and html and can output
17
- it to standard out or to a file.
18
- EOF
19
- spec.license = 'BSD-2-Clause'
20
- spec.version = RubyProf::VERSION
21
-
22
- spec.metadata = {
23
- "bug_tracker_uri" => "https://github.com/ruby-prof/ruby-prof/issues",
24
- "changelog_uri" => "https://github.com/ruby-prof/ruby-prof/blob/master/CHANGES",
25
- "documentation_uri" => "https://ruby-prof.github.io/",
26
- "source_code_uri" => "https://github.com/ruby-prof/ruby-prof/tree/v#{spec.version}",
27
- }
28
-
29
- spec.author = "Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes"
30
- spec.email = "shugo@ruby-lang.org, cfis@savagexi.com, rogerdpack@gmail.com, skaes@railsexpress.de"
31
- spec.platform = Gem::Platform::RUBY
32
- spec.require_path = "lib"
33
- spec.bindir = "bin"
34
- spec.executables = ["ruby-prof", "ruby-prof-check-trace"]
35
- spec.extensions = ["ext/ruby_prof/extconf.rb"]
36
- spec.files = Dir['CHANGES',
37
- 'LICENSE',
38
- 'Rakefile',
39
- 'README.md',
40
- 'ruby-prof.gemspec',
41
- 'bin/ruby-prof',
42
- 'bin/ruby-prof-check-trace',
43
- 'doc/**/*',
44
- 'examples/*',
45
- 'ext/ruby_prof/extconf.rb',
46
- 'ext/ruby_prof/*.c',
47
- 'ext/ruby_prof/*.h',
48
- 'ext/ruby_prof/vc/*.sln',
49
- 'ext/ruby_prof/vc/*.vcxproj',
50
- 'lib/ruby-prof.rb',
51
- 'lib/unprof.rb',
52
- 'lib/ruby-prof/*.rb',
53
- 'lib/ruby-prof/assets/*',
54
- 'lib/ruby-prof/profile/*.rb',
55
- 'lib/ruby-prof/printers/*.rb',
56
- 'test/*.rb']
57
-
58
- spec.test_files = Dir["test/test_*.rb"]
59
- spec.required_ruby_version = '>= 3.0.0'
60
- spec.date = Time.now.strftime('%Y-%m-%d')
61
- spec.homepage = 'https://github.com/ruby-prof/ruby-prof'
62
- spec.add_development_dependency("base64")
63
- spec.add_development_dependency('minitest')
64
- spec.add_development_dependency('rake-compiler')
65
- end
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "ruby-prof/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ruby-prof"
8
+
9
+ spec.homepage = "https://github.com/ruby-prof/ruby-prof/"
10
+ spec.summary = "Fast Ruby profiler"
11
+ spec.description = <<-EOF
12
+ ruby-prof is a fast code profiler for Ruby. It is a C extension and
13
+ therefore is many times faster than the standard Ruby profiler. It
14
+ supports both flat and graph profiles. For each method, graph profiles
15
+ show how long the method ran, which methods called it and which
16
+ methods it called. RubyProf generate both text and html and can output
17
+ it to standard out or to a file.
18
+ EOF
19
+ spec.license = 'BSD-2-Clause'
20
+ spec.version = RubyProf::VERSION
21
+
22
+ spec.metadata = {
23
+ "bug_tracker_uri" => "https://github.com/ruby-prof/ruby-prof/issues",
24
+ "changelog_uri" => "https://github.com/ruby-prof/ruby-prof/blob/master/CHANGES",
25
+ "documentation_uri" => "https://ruby-prof.github.io/",
26
+ "source_code_uri" => "https://github.com/ruby-prof/ruby-prof/tree/v#{spec.version}",
27
+ }
28
+
29
+ spec.author = "Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes"
30
+ spec.email = "shugo@ruby-lang.org, cfis@savagexi.com, rogerdpack@gmail.com, skaes@railsexpress.de"
31
+ spec.platform = Gem::Platform::RUBY
32
+ spec.require_path = "lib"
33
+ spec.bindir = "bin"
34
+ spec.executables = ["ruby-prof", "ruby-prof-check-trace"]
35
+ spec.extensions = ["ext/ruby_prof/extconf.rb"]
36
+ spec.files = Dir['CHANGES',
37
+ 'LICENSE',
38
+ 'Rakefile',
39
+ 'README.md',
40
+ 'ruby-prof.gemspec',
41
+ 'bin/ruby-prof',
42
+ 'bin/ruby-prof-check-trace',
43
+ 'doc/**/*',
44
+ 'examples/*',
45
+ 'ext/ruby_prof/extconf.rb',
46
+ 'ext/ruby_prof/*.c',
47
+ 'ext/ruby_prof/*.h',
48
+ 'ext/ruby_prof/vc/*.sln',
49
+ 'ext/ruby_prof/vc/*.vcxproj',
50
+ 'lib/ruby-prof.rb',
51
+ 'lib/unprof.rb',
52
+ 'lib/ruby-prof/*.rb',
53
+ 'lib/ruby-prof/assets/*',
54
+ 'lib/ruby-prof/profile/*.rb',
55
+ 'lib/ruby-prof/printers/*.rb',
56
+ 'test/*.rb']
57
+
58
+ spec.test_files = Dir["test/test_*.rb"]
59
+ spec.required_ruby_version = '>= 3.0.0'
60
+ spec.date = Time.now.strftime('%Y-%m-%d')
61
+ spec.homepage = 'https://github.com/ruby-prof/ruby-prof'
62
+ spec.add_dependency('base64')
63
+ spec.add_development_dependency('minitest')
64
+ spec.add_development_dependency('rake-compiler')
65
+ spec.add_development_dependency('rdoc')
66
+ end
@@ -35,27 +35,15 @@ class DynamicMethodTest < TestCase
35
35
 
36
36
  methods = result.threads.first.methods.sort.reverse
37
37
 
38
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1')
39
- expected_method_names = %w(
40
- DynamicMethodTest#test_dynamic_method
41
- Kernel#sleep
42
- DynamicMethodTest::FruitMedley#peach
43
- DynamicMethodTest::FruitMedley#banana
44
- DynamicMethodTest::FruitMedley#orange
45
- DynamicMethodTest::FruitMedley#apple
46
- Symbol#to_s
47
- )
48
- else
49
- expected_method_names = %w(
50
- DynamicMethodTest#test_dynamic_method
51
- Kernel#sleep
52
- DynamicMethodTest::FruitMedley#peach
53
- DynamicMethodTest::FruitMedley#banana
54
- DynamicMethodTest::FruitMedley#orange
55
- DynamicMethodTest::FruitMedley#apple
56
- Integer#==
57
- )
58
- end
38
+ expected_method_names = %w(
39
+ DynamicMethodTest#test_dynamic_method
40
+ Kernel#sleep
41
+ DynamicMethodTest::FruitMedley#peach
42
+ DynamicMethodTest::FruitMedley#banana
43
+ DynamicMethodTest::FruitMedley#orange
44
+ DynamicMethodTest::FruitMedley#apple
45
+ Integer#==
46
+ )
59
47
 
60
48
  assert_equal expected_method_names.join("\n"), methods.map(&:full_name).join("\n")
61
49
  end
@@ -1,21 +1,23 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # -- Test for bug
7
- # http://github.com/rdp/ruby-prof/issues#issue/12
8
-
9
- class EnumerableTest < TestCase
10
- def test_enumerable
11
- result = RubyProf::Profile.profile do
12
- 3.times { [1,2,3].any? {|n| n} }
13
- end
14
- methods = if RUBY_VERSION >= "3.3.0"
15
- %w(EnumerableTest#test_enumerable Integer#times Kernel#block_given? Integer#< Array#any? Integer#succ)
16
- else
17
- %w(EnumerableTest#test_enumerable Integer#times Array#any?)
18
- end
19
- assert_equal(methods, result.threads.first.methods.map(&:full_name))
20
- end
21
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ # -- Test for bug
7
+ # http://github.com/rdp/ruby-prof/issues#issue/12
8
+
9
+ class EnumerableTest < TestCase
10
+ def test_enumerable
11
+ result = RubyProf::Profile.profile do
12
+ 3.times { [1,2,3].any? {|n| n} }
13
+ end
14
+ methods = if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.3')
15
+ %w(EnumerableTest#test_enumerable Integer#times Array#any?)
16
+ elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4')
17
+ %w(EnumerableTest#test_enumerable Integer#times Kernel#block_given? Integer#< Array#any? Integer#succ)
18
+ else
19
+ %w(EnumerableTest#test_enumerable Integer#times Integer#< Array#any? Integer#succ)
20
+ end
21
+ assert_equal(methods, result.threads.first.methods.map(&:full_name))
22
+ end
23
+ end