profiling 2.0.1 → 4.0.0
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.
- checksums.yaml +5 -5
- data/README.md +37 -22
- data/bin/console +4 -3
- data/lib/profiling.rb +3 -1
- data/lib/profiling/configuration.rb +4 -3
- data/lib/profiling/engine.rb +26 -23
- data/lib/profiling/version.rb +3 -1
- metadata +28 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 741bfb137712d65a0280ccde370760c2f9993e07fc5f247ee7e796fa99913caa
|
4
|
+
data.tar.gz: 90bf533152d0f512c381cb79ef3cffb201c4905bfe59876e1e43ea27939f5b58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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', "~>
|
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
|
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
|
-
|
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.
|
56
|
-
dir: '
|
57
|
-
exclude_gems: true,
|
58
|
-
exclude_standard_lib:
|
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.
|
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
|
-
##
|
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
|
-
|
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("
|
103
|
+
Profiler.run("some-label-#{Time.now.to_i}") do
|
89
104
|
# Slow code here...
|
90
105
|
end
|
91
106
|
```
|
92
107
|
|
93
|
-
|
108
|
+
### Organizing
|
94
109
|
|
95
|
-
|
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
|
4
|
-
require
|
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
|
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__)
|
6
|
+
Dir["#{File.dirname(__FILE__)}/profiling/*.rb"].each { |file| require file }
|
5
7
|
|
6
8
|
class Profiler
|
7
9
|
extend Configuration
|
data/lib/profiling/engine.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Profiler
|
2
4
|
module Engine
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
#
|
33
|
-
|
34
|
-
|
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,
|
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,
|
60
|
-
RubyProf::
|
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,
|
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
|
data/lib/profiling/version.rb
CHANGED
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:
|
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:
|
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: '
|
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: '
|
26
|
+
version: '2.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: pry
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
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: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
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: '
|
54
|
+
version: '13.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
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: '
|
68
|
+
version: '3.10'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
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: '
|
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: '
|
111
|
-
description:
|
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:
|
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
|
-
|
148
|
-
|
149
|
-
signing_key:
|
147
|
+
rubygems_version: 3.2.3
|
148
|
+
signing_key:
|
150
149
|
specification_version: 4
|
151
|
-
summary:
|
152
|
-
the ruby-prof gem to do simple but powerful profiling'
|
150
|
+
summary: Non-discriminatory profiler for Ruby MRI code.
|
153
151
|
test_files: []
|