profiling 2.0.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 93ace3273f3436ce25c317fbad89c277548c9af4
4
- data.tar.gz: 37ecc2ab961d454be1a4461af1728a815f830ea0
2
+ SHA256:
3
+ metadata.gz: 741bfb137712d65a0280ccde370760c2f9993e07fc5f247ee7e796fa99913caa
4
+ data.tar.gz: 90bf533152d0f512c381cb79ef3cffb201c4905bfe59876e1e43ea27939f5b58
5
5
  SHA512:
6
- metadata.gz: 9b820255232fea158d0d25184ae3597a4a73b664ce2df1a0b8bd520d5b28197c04134bd8a8d5eee0a8f6fe21b546a2c96821daf3e4f7e7ef0446865f49c7eab4
7
- data.tar.gz: 7c5f38ac38441ff62a5f03a27d64cd04c662b67b00b98ba6928c8d52e8fe2ed56a3bba744da7b5d806dda475356a74e1c377ffcd41436d305701bb02809155dd
6
+ metadata.gz: e11902ff7667a4b38e19c9ee9e60a0f2301ad86d28d30807b1b7e8fa9c6aa201b15e7ef58585d16f39ff7487680a8a84a1b0a348aa3ce3b3a0ddc1c32eb6664c
7
+ data.tar.gz: 7ebb82d01f71104d1ba1be6671555db8bcd8319a06719f46b500809fe535b611444db4d8b167cb49971c4f6a57518199ffdc74581e4f94ead8327fa8e4f5a5a4
data/README.md CHANGED
@@ -12,7 +12,7 @@ Non-discriminatory profiling for your MRI Ruby code. This gem is a small wrapper
12
12
  Add this line to your application's Gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'profiling', "~> 1.2"
15
+ gem 'profiling', "~> 4.0"
16
16
  ```
17
17
 
18
18
  And then execute:
@@ -31,15 +31,9 @@ Profile slow code from your friend or colleague like this:
31
31
  Profiler.run do
32
32
  # Slow code here...
33
33
  end
34
-
35
- # or
36
-
37
- Profiler.run("some-label") do
38
- # Slow code here...
39
- end
40
34
  ```
41
35
 
42
- The next time you call the code it will be profiled and three files will be written into a directory `profiling`, and in the second example `profiling/some-label`.
36
+ The next time you call the code it will be profiled and three files will be written into a directory called `profiling`.
43
37
 
44
38
  ### Files Generated
45
39
 
@@ -49,25 +43,36 @@ The next time you call the code it will be profiled and three files will be writ
49
43
  | `stack.html` | See the profiled code as a nested stack |
50
44
  | `flat.txt` | List of all functions called, the time spent in each and the number of calls made to that function |
51
45
 
52
- ## Configuration
46
+ ### Is it Fast?
47
+
48
+ No, no it's not. It's really slow. For especially gnarly, deeply nested code you will want to get up and get a coffee. This gem wraps [ruby-prof](https://github.com/ruby-prof/ruby-prof) which is partly written in C, so it's as fast as it can be.
49
+ ## Options
50
+
51
+ Use the `configure` method to set some options:
53
52
 
54
53
  ```ruby
55
- Profiler.config = {
56
- dir: 'profiling', # Directory the files will be created in (default is 'profiling')
57
- exclude_gems: true, # Exclude ruby gems from the results (default is true)
58
- exclude_standard_lib: false # Exclude ruby standard library from results (default is false)
59
- }
54
+ Profiler.configure({
55
+ dir: '/tmp/my-dir',
56
+ exclude_gems: true,
57
+ exclude_standard_lib: true
58
+ })
60
59
  ```
61
60
 
61
+ | Option | Description | Default |
62
+ | ------ | --------|------------ |
63
+ | `dir` | Directory the files will be created in (can be relative or absolute) | `"profiling"` |
64
+ | `exclude_gems` | Exclude ruby gems from the results | `false` |
65
+ | `exclude_standard_lib` | Exclude ruby standard library from results | `false` |
66
+
62
67
  ## Rails Initializer
63
68
 
64
69
  This initializer is recommended if you're planning to profile in Rails:
65
70
 
66
71
  ```ruby
67
72
  # config/initializer/profiling.rb
68
- Profiler.config = {
73
+ Profiler.configure({
69
74
  dir: Rails.root.join('tmp/profiling')
70
- }
75
+ })
71
76
  ```
72
77
 
73
78
  ## Conditional Profiling
@@ -80,19 +85,29 @@ Profiler.run(if: user.is_admin?) do
80
85
  end
81
86
  ```
82
87
 
83
- ## Preserving artefacts
88
+ ## Labels
89
+
90
+ Labels translate to sub directories that the files will be generated in. This is handy for profiling multiple things at once, preserving files between runs, or grouping profiling results logically.
91
+
92
+ ```ruby
93
+ Profiler.run("some-label") do
94
+ # Slow code here...
95
+ end
96
+ ```
97
+
98
+ ### Preserving files between runs
84
99
 
85
- Every time code is profiled the previous files will be overwritten unless the label is dynamic. To keep old files, add the current time in the label so new files are generated with each run:
100
+ Keep old files by adding the current time in the label so new files are generated with each run:
86
101
 
87
102
  ```ruby
88
- Profiler.run("my-label-#{Time.now.to_i}") do
103
+ Profiler.run("some-label-#{Time.now.to_i}") do
89
104
  # Slow code here...
90
105
  end
91
106
  ```
92
107
 
93
- ## Organizing artefacts
108
+ ### Organizing
94
109
 
95
- Labels translate to directories, so use `/` in your labels to group artefacts together:
110
+ Use `/` in your labels to group profiling results together in directories:
96
111
 
97
112
  ```ruby
98
113
  Profiler.run("post/create") do
@@ -106,7 +121,7 @@ end
106
121
 
107
122
  ## Contributing
108
123
 
109
- Bug reports and pull requests are welcome.
124
+ Bug reports and pull requests are welcome. Pull requests with passing tests are even better.
110
125
 
111
126
  To run the test suite:
112
127
 
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "profiling"
4
+ require 'bundler/setup'
5
+ require 'profiling'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "profiling"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
data/lib/profiling.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
  require 'ostruct'
3
5
 
4
- Dir[File.dirname(__FILE__) + '/profiling/*.rb'].each { |file| require file }
6
+ Dir["#{File.dirname(__FILE__)}/profiling/*.rb"].each { |file| require file }
5
7
 
6
8
  class Profiler
7
9
  extend Configuration
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Profiler
2
4
  module Configuration
3
-
4
5
  DEFAULT_CONFIG = {
5
6
  dir: 'profiling',
6
- exclude_gems: true,
7
+ exclude_gems: false,
7
8
  exclude_standard_lib: false
8
- }
9
+ }.freeze
9
10
 
10
11
  attr_accessor :config
11
12
 
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Profiler
2
4
  module Engine
3
-
4
- def run(label=nil, options={})
5
- enabled = options[:if].nil? ? true : !!options[:if]
5
+ def run(*args)
6
+ label = args.find { |a| a.is_a?(String) }
7
+ opts = args.find { |a| a.is_a?(Hash) }
8
+ enabled = opts.nil? ? true : opts[:if]
6
9
  return yield unless enabled
7
10
 
8
11
  # Create directory
@@ -22,48 +25,48 @@ class Profiler
22
25
 
23
26
  begin
24
27
  yield
25
- rescue => e
28
+ rescue StandardError => e
26
29
  profile.stop
27
30
  raise e
28
31
  end
29
32
 
30
33
  @results = profile.stop
31
34
 
32
- # Remove certain things from the profiling
33
- unless @results.threads.empty?
34
- exclude_paths = []
35
-
36
- if config[:exclude_gems]
37
- exclude_paths << /\/gems\//
38
- end
39
-
40
- unless exclude_paths.empty?
41
- @results.threads.first.methods.each do |method|
42
- if exclude_paths.any?{|regex| method.source_file.match(regex) }
43
- method.eliminate!
44
- end
45
- end
35
+ # Optionally remove gems (and the remainder of any standard lib) from the results
36
+ if !@results.threads.empty? && exclusion_regex
37
+ @results.threads.each do |thread|
38
+ thread.methods.each { |m| m.eliminate! if m.source_file.match(exclusion_regex) }
46
39
  end
47
40
  end
48
41
 
49
- out()
42
+ out
50
43
  end
51
44
 
52
45
  private
53
46
 
54
47
  def out
55
- File.open(File.join(@dir, "graph.html"), 'w') do |file|
48
+ File.open(File.join(@dir, 'graph.html'), 'w') do |file|
56
49
  RubyProf::GraphHtmlPrinter.new(@results).print(file)
57
50
  end
58
51
 
59
- File.open(File.join(@dir, "flat.txt"), 'w') do |file|
60
- RubyProf::FlatPrinterWithLineNumbers.new(@results).print(file)
52
+ File.open(File.join(@dir, 'flat.txt'), 'w') do |file|
53
+ RubyProf::FlatPrinter.new(@results).print(file)
61
54
  end
62
55
 
63
- File.open(File.join(@dir, "stack.html"), 'w') do |file|
56
+ File.open(File.join(@dir, 'stack.html'), 'w') do |file|
64
57
  RubyProf::CallStackPrinter.new(@results).print(file)
65
58
  end
66
59
  end
67
60
 
61
+ def exclusion_regex
62
+ root = '/lib/ruby/'
63
+ if config[:exclude_gems] && config[:exclude_standard_lib]
64
+ /#{root}/
65
+ elsif config[:exclude_gems]
66
+ %r{#{root}gems/}
67
+ elsif config[:exclude_standard_lib]
68
+ /#{root}[^g]/
69
+ end
70
+ end
68
71
  end
69
72
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Profiler
2
- VERSION = "2.0.1"
4
+ VERSION = '4.0.0'
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: profiling
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Duncalfe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-20 00:00:00.000000000 Z
11
+ date: 2021-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,100 +16,100 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2.2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '2.2'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: pry
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec_junit_formatter
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.3'
61
+ version: '3.10'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.3'
68
+ version: '3.10'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry
70
+ name: rspec_junit_formatter
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '0.4'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '0.4'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: yard
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '0.9'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '0.9'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: ruby-prof
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.17'
103
+ version: '1.4'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.17'
111
- description: 'Non-discriminatory Ruby code profiling: This gem is a small wrapper
112
- around the ruby-prof gem to do simple but powerful profiling'
110
+ version: '1.4'
111
+ description: Non-discriminatory profiler for Ruby MRI code. This gem is a small wrapper
112
+ around the ruby-prof gem to do simple but powerful profiling
113
113
  email:
114
114
  - lduncalfe@eml.cc
115
115
  executables: []
@@ -129,7 +129,7 @@ licenses:
129
129
  - MIT
130
130
  metadata:
131
131
  yard.run: yri
132
- post_install_message:
132
+ post_install_message:
133
133
  rdoc_options: []
134
134
  require_paths:
135
135
  - lib
@@ -137,17 +137,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
137
  requirements:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
- version: 1.9.3
140
+ version: 2.5.0
141
141
  required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  requirements: []
147
- rubyforge_project:
148
- rubygems_version: 2.4.5.1
149
- signing_key:
147
+ rubygems_version: 3.2.3
148
+ signing_key:
150
149
  specification_version: 4
151
- summary: 'Non-discriminatory Ruby code profiling: This gem is a small wrapper around
152
- the ruby-prof gem to do simple but powerful profiling'
150
+ summary: Non-discriminatory profiler for Ruby MRI code.
153
151
  test_files: []