method_profiler 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/lib/method_profiler/profiler.rb +18 -18
- data/lib/method_profiler/report.rb +13 -10
- data/method_profiler.gemspec +1 -1
- data/spec/method_profiler/profiler_spec.rb +6 -0
- data/spec/method_profiler/report_spec.rb +26 -31
- data/spec/support/petition.rb +6 -0
- metadata +25 -9
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/README.md
CHANGED
@@ -11,8 +11,8 @@ Create a new profiler by passing the object you want to profile to `MethodProfil
|
|
11
11
|
```ruby
|
12
12
|
profiler = MethodProfiler.observe(MyClass)
|
13
13
|
|
14
|
-
MyClass.
|
15
|
-
MyClass.
|
14
|
+
MyClass.labore_voluptatum
|
15
|
+
MyClass.labore_voluptatum
|
16
16
|
|
17
17
|
my_obj = MyClass.new
|
18
18
|
|
@@ -66,7 +66,7 @@ MethodProfiler results for: MyClass
|
|
66
66
|
puts profiler.report.sort_by(:total_calls).order(:ascending)
|
67
67
|
```
|
68
68
|
|
69
|
-
`#sort_by` accepts a symbol or string with the name of any of the columns in the table: `:method`, `:min`, `:max`, `:average`, or `:total_calls`.
|
69
|
+
`#sort_by` accepts a symbol or string with the name of any of the columns in the table: `:method`, `:min`, `:max`, `:average`, `:total_time`, or `:total_calls`.
|
70
70
|
|
71
71
|
`#order` accepts a symbol or string of `:ascending` or `:descending`. These can also be abbreviated with `:asc` and `:desc`.
|
72
72
|
|
data/Rakefile
CHANGED
@@ -33,8 +33,9 @@ module MethodProfiler
|
|
33
33
|
|
34
34
|
def wrap_methods_with_profiling
|
35
35
|
profiler = self
|
36
|
-
singleton_methods_to_wrap =
|
37
|
-
instance_methods_to_wrap =
|
36
|
+
singleton_methods_to_wrap = @obj.methods(false)
|
37
|
+
instance_methods_to_wrap = @obj.instance_methods(false)
|
38
|
+
private_instance_methods_to_wrap = @obj.private_instance_methods(false)
|
38
39
|
|
39
40
|
@obj.singleton_class.module_eval do
|
40
41
|
singleton_methods_to_wrap.each do |method|
|
@@ -57,24 +58,24 @@ module MethodProfiler
|
|
57
58
|
alias_method method, "#{method}_with_profiling"
|
58
59
|
end
|
59
60
|
end
|
60
|
-
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
@obj.module_eval do
|
63
|
+
private_instance_methods_to_wrap.each do |method|
|
64
|
+
define_method("#{method}_with_profiling") do |*args, &block|
|
65
|
+
profiler.send(:profile, method) { send("#{method}_without_profiling", *args, &block) }
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
alias_method "#{method}_without_profiling", method
|
69
|
+
alias_method method, "#{method}_with_profiling"
|
70
|
+
|
71
|
+
private "#{method}_with_profiling"
|
72
|
+
end
|
73
|
+
end
|
72
74
|
end
|
73
75
|
|
74
76
|
def profile(method, singleton = false, &block)
|
75
77
|
method_name = singleton ? ".#{method}" : "##{method}"
|
76
|
-
result =
|
77
|
-
elapsed_time, result = benchmark(result, &block)
|
78
|
+
elapsed_time, result = benchmark(block)
|
78
79
|
elapsed_time = elapsed_time.to_s.match(/\(\s*([^\)]+)\)/)[1].to_f
|
79
80
|
@data[method_name] << elapsed_time
|
80
81
|
result
|
@@ -100,10 +101,9 @@ module MethodProfiler
|
|
100
101
|
results
|
101
102
|
end
|
102
103
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
elapsed_time = Benchmark.measure { result = block.call }
|
104
|
+
def benchmark(block_to_benchmark)
|
105
|
+
result = nil
|
106
|
+
elapsed_time = Benchmark.measure { result = block_to_benchmark.call }
|
107
107
|
return elapsed_time, result
|
108
108
|
end
|
109
109
|
end
|
@@ -5,8 +5,18 @@ module MethodProfiler
|
|
5
5
|
# Sorts and displays data collected by a {Profiler}.
|
6
6
|
#
|
7
7
|
class Report
|
8
|
+
# Report headers
|
9
|
+
HEADERS = {
|
10
|
+
:method => "Method",
|
11
|
+
:min => "Min Time",
|
12
|
+
:max => "Max Time",
|
13
|
+
:average => "Average Time",
|
14
|
+
:total_time => "Total Time",
|
15
|
+
:total_calls => "Total Calls",
|
16
|
+
}
|
17
|
+
|
8
18
|
# Fields that can be passed to {#sort_by}.
|
9
|
-
FIELDS =
|
19
|
+
FIELDS = HEADERS.keys
|
10
20
|
|
11
21
|
# Directions that can be passed to {#order}.
|
12
22
|
DIRECTIONS = [:asc, :ascending, :desc, :descending]
|
@@ -68,15 +78,8 @@ module MethodProfiler
|
|
68
78
|
"MethodProfiler results for: #{@obj}",
|
69
79
|
Hirb::Helpers::Table.render(
|
70
80
|
to_a,
|
71
|
-
:headers =>
|
72
|
-
|
73
|
-
:min => "Min Time",
|
74
|
-
:max => "Max Time",
|
75
|
-
:average => "Average Time",
|
76
|
-
:total_time => "Total Time",
|
77
|
-
:total_calls => "Total Calls",
|
78
|
-
},
|
79
|
-
:fields => [:method, :min, :max, :average, :total_time, :total_calls],
|
81
|
+
:headers => HEADERS.dup,
|
82
|
+
:fields => FIELDS.dup,
|
80
83
|
:filters => {
|
81
84
|
:min => :to_milliseconds,
|
82
85
|
:max => :to_milliseconds,
|
data/method_profiler.gemspec
CHANGED
@@ -9,6 +9,8 @@ describe MethodProfiler::Profiler do
|
|
9
9
|
petition.should respond_to(:foo_with_profiling)
|
10
10
|
petition.should respond_to(:foo_without_profiling)
|
11
11
|
petition.should_not respond_to(:foo_with_profiling_with_profiling)
|
12
|
+
petition.private_methods.should include(:shh_with_profiling)
|
13
|
+
petition.private_methods.should include(:shh_without_profiling)
|
12
14
|
end
|
13
15
|
|
14
16
|
it "returns correct values for class methods" do
|
@@ -19,6 +21,10 @@ describe MethodProfiler::Profiler do
|
|
19
21
|
petition.baz.should == "blah"
|
20
22
|
end
|
21
23
|
|
24
|
+
it "returns correct values for private methods" do
|
25
|
+
petition.send(:shh).should == "secret"
|
26
|
+
end
|
27
|
+
|
22
28
|
it "yields to implicit blocks" do
|
23
29
|
petition.method_with_implicit_block {|v| v }.should == "implicit"
|
24
30
|
end
|
@@ -5,15 +5,15 @@ describe MethodProfiler::Report do
|
|
5
5
|
profiler = MethodProfiler::Profiler.new(Petition)
|
6
6
|
|
7
7
|
# Fake the timings for testing purposes
|
8
|
-
profiler.stub(:benchmark) do |
|
9
|
-
result =
|
8
|
+
profiler.stub(:benchmark) do |block_to_benchmark|
|
9
|
+
result = block_to_benchmark.call
|
10
10
|
"(#{rand})"
|
11
11
|
end
|
12
12
|
|
13
13
|
petition = Petition.new
|
14
14
|
|
15
|
-
[:hay, :
|
16
|
-
[:foo, :bar, :baz].each { |m| petition.send(m) }
|
15
|
+
[:hay, :guys].each { |m| petition.class.send(m) }
|
16
|
+
[:foo, :bar, :baz, :shh].each { |m| petition.send(m) }
|
17
17
|
|
18
18
|
@report = profiler.report
|
19
19
|
end
|
@@ -22,57 +22,51 @@ describe MethodProfiler::Report do
|
|
22
22
|
it "returns an array of records" do
|
23
23
|
results = @report.to_a
|
24
24
|
results.should be_an Array
|
25
|
-
results.size.should ==
|
25
|
+
results.size.should == 6
|
26
26
|
end
|
27
27
|
|
28
|
-
it "
|
28
|
+
it "returns results sorted by average time (descending) by default" do
|
29
29
|
results = @report.to_a
|
30
30
|
average_times = results.map { |r| r[:average] }
|
31
31
|
average_times.should == average_times.sort.reverse
|
32
32
|
end
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
+
describe "#sort_by" do
|
36
|
+
it "sets the result key to order results by" do
|
35
37
|
results = @report.sort_by(:min).to_a
|
36
38
|
min_times = results.map { |r| r[:min] }
|
37
39
|
min_times.should == min_times.sort.reverse
|
38
40
|
end
|
39
41
|
|
40
|
-
it "sorts in a different direction if it's been changed" do
|
41
|
-
results = @report.order(:ascending).to_a
|
42
|
-
average_times = results.map { |r| r[:average] }
|
43
|
-
average_times.should == average_times.sort
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#sort_by" do
|
48
|
-
it "sets the sort type" do
|
49
|
-
@report.sort_by(:total_calls)
|
50
|
-
@report.instance_variable_get("@sort_by").should == :total_calls
|
51
|
-
end
|
52
|
-
|
53
42
|
it "defaults to average if an invalid sort type is passed" do
|
54
|
-
@report.sort_by(:foo)
|
55
|
-
|
43
|
+
results = @report.sort_by(:foo).to_a
|
44
|
+
average_times = results.map { |r| r[:average] }
|
45
|
+
average_times.should == average_times.sort.reverse
|
56
46
|
end
|
57
47
|
end
|
58
48
|
|
59
49
|
describe "#order" do
|
60
50
|
it "sets the sort direction" do
|
61
|
-
@report.order(:ascending)
|
62
|
-
|
51
|
+
results = @report.order(:ascending).to_a
|
52
|
+
average_times = results.map { |r| r[:average] }
|
53
|
+
average_times.should == average_times.sort
|
63
54
|
end
|
64
55
|
|
65
56
|
it "defaults to descending if an invalid direction is passed" do
|
66
|
-
@report.order(:foo)
|
67
|
-
|
57
|
+
results = @report.order(:foo).to_a
|
58
|
+
average_times = results.map { |r| r[:average] }
|
59
|
+
average_times.should == average_times.sort.reverse
|
68
60
|
end
|
69
61
|
|
70
|
-
it "allows
|
71
|
-
@report.order(:asc)
|
72
|
-
|
62
|
+
it "allows :asc and :desc aliases" do
|
63
|
+
results = @report.order(:asc).to_a
|
64
|
+
average_times = results.map { |r| r[:average] }
|
65
|
+
average_times.should == average_times.sort
|
73
66
|
|
74
|
-
@report.order(:desc)
|
75
|
-
|
67
|
+
results = @report.order(:desc).to_a
|
68
|
+
average_times = results.map { |r| r[:average] }
|
69
|
+
average_times.should == average_times.sort.reverse
|
76
70
|
end
|
77
71
|
end
|
78
72
|
|
@@ -86,6 +80,7 @@ describe MethodProfiler::Report do
|
|
86
80
|
output.scan(/#foo/).size.should == 1
|
87
81
|
output.scan(/#bar/).size.should == 1
|
88
82
|
output.scan(/#baz/).size.should == 1
|
83
|
+
output.scan(/#shh/).size.should == 1
|
89
84
|
end
|
90
85
|
end
|
91
86
|
end
|
data/spec/support/petition.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: method_profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hirb
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.6.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.6.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rspec
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: simplecov
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,7 +53,12 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
description: MethodProfiler observes your code and generates reports about the methods
|
48
63
|
that were run and how long they took.
|
49
64
|
email:
|
@@ -53,6 +68,7 @@ extensions: []
|
|
53
68
|
extra_rdoc_files: []
|
54
69
|
files:
|
55
70
|
- .gitignore
|
71
|
+
- .rspec
|
56
72
|
- .travis.yml
|
57
73
|
- Gemfile
|
58
74
|
- LICENSE
|
@@ -89,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
105
|
version: '0'
|
90
106
|
requirements: []
|
91
107
|
rubyforge_project:
|
92
|
-
rubygems_version: 1.8.
|
108
|
+
rubygems_version: 1.8.23
|
93
109
|
signing_key:
|
94
110
|
specification_version: 3
|
95
111
|
summary: Find slow methods in your program.
|