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 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.nisi_inventore
15
- MyClass.nisi_inventore
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
@@ -2,6 +2,6 @@ require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
4
  desc "Run specs"
5
- RSpec::Core::RakeTask.new { |t| t.rspec_opts = "--color" }
5
+ RSpec::Core::RakeTask.new(:spec)
6
6
 
7
7
  task :default => :spec
@@ -33,8 +33,9 @@ module MethodProfiler
33
33
 
34
34
  def wrap_methods_with_profiling
35
35
  profiler = self
36
- singleton_methods_to_wrap = find_singleton_methods
37
- instance_methods_to_wrap = find_instance_methods
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
- def find_singleton_methods
63
- @obj.singleton_class.instance_methods - @obj.singleton_class.ancestors.map do |a|
64
- a == @obj ? [] : a.instance_methods
65
- end.flatten
66
- end
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
- def find_instance_methods
69
- @obj.instance_methods - @obj.ancestors.map do |a|
70
- a == @obj ? [] : a.instance_methods
71
- end.flatten
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 = nil
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
- private
104
-
105
- def benchmark(result, &block)
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 = [:method, :min, :max, :average, :total_time, :total_calls]
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
- :method => "Method",
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,
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "method_profiler"
5
- s.version = "1.1.0"
5
+ s.version = "1.2.0"
6
6
  s.authors = ["Jimmy Cuadra"]
7
7
  s.email = ["jimmy@jimmycuadra.com"]
8
8
  s.homepage = "https://github.com/change/method_profiler"
@@ -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 |result, block|
9
- result = block.call
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, :hay, :guys].each { |m| petition.class.send(m) }
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 == 5
25
+ results.size.should == 6
26
26
  end
27
27
 
28
- it "sorts by average time (descending) by default" do
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
- it "sorts by another type if it's been changed" do
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
- @report.instance_variable_get("@sort_by").should == :average
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
- @report.instance_variable_get("@order").should == :ascending
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
- @report.instance_variable_get("@order").should == :descending
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 normalizes :asc and :desc aliases" do
71
- @report.order(:asc)
72
- @report.instance_variable_get("@order").should == :ascending
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
- @report.instance_variable_get("@order").should == :descending
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
@@ -31,4 +31,10 @@ class Petition
31
31
  def method_with_explicit_block_and_args(*args, &block)
32
32
  block.call args
33
33
  end
34
+
35
+ private
36
+
37
+ def shh
38
+ "secret"
39
+ end
34
40
  end
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.1.0
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: 2012-03-10 00:00:00.000000000 Z
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: &70291604515080 !ruby/object:Gem::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: *70291604515080
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: &70291604514680 !ruby/object:Gem::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: *70291604514680
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: &70291604514220 !ruby/object:Gem::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: *70291604514220
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.17
108
+ rubygems_version: 1.8.23
93
109
  signing_key:
94
110
  specification_version: 3
95
111
  summary: Find slow methods in your program.