sampling_prof 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/README.md +101 -0
- data/lib/sampling_prof/internal.rb +7 -3
- data/lib/sampling_prof.jar +0 -0
- data/lib/sampling_prof.rb +2 -1
- metadata +49 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09e40af6cfc090cd8cb6f7898ca0f51caf42c567
|
4
|
+
data.tar.gz: 68069a76e4e43c35e3db126fe40fd60637aab510
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7aa1b85fe7a29d053f3f10659807f3d7e22bc4479a5115261b23056803082ccc40844f37163956accc6b10b256a451ee7b1a7d4efb7c64999b7de90ff63fcf9
|
7
|
+
data.tar.gz: 53ff7d0f03ca3b510dcba853fdaa9343e7abcf471d55f5d4648f0e9a2b2e665a33cb9a851624ecaba1f4acefefb365b52996ce1181681630524c1cb2e4a8736c
|
data/README.md
CHANGED
@@ -0,0 +1,101 @@
|
|
1
|
+
SamplingProf
|
2
|
+
===============
|
3
|
+
|
4
|
+
SamplingProf is a profiling tool that operates by sampling your running thread stacktrace. The result is statistical approximation, but it allows your code to run near full speed.
|
5
|
+
|
6
|
+
Quick start
|
7
|
+
---------------
|
8
|
+
|
9
|
+
For single thread profiling, start with default options:
|
10
|
+
|
11
|
+
prof = SamplingProf.new
|
12
|
+
prof.profile do
|
13
|
+
... your code ...
|
14
|
+
end
|
15
|
+
|
16
|
+
After profiling finished, the output will be write to file SamplingProf::DEFAULT_OUTPUT_FILE
|
17
|
+
|
18
|
+
Options
|
19
|
+
---------------
|
20
|
+
|
21
|
+
SamplingProf class initializer takes 3 arguments:
|
22
|
+
|
23
|
+
1. sampling interval: seconds
|
24
|
+
2. multithreading: boolean
|
25
|
+
3. output interval: seconds
|
26
|
+
|
27
|
+
SamplingProf class also takes block as another option to overwite default output handler, the default output handler will write output data to a local file defined by output_file attribute, which is default to SamplingProf::DEFAULT_OUTPUT_FILE
|
28
|
+
|
29
|
+
### Sampling interval
|
30
|
+
|
31
|
+
This is an interval to control how frequent SamplingProf should take sample of target thread stacktrace.
|
32
|
+
The default value is 0.1 seconds.
|
33
|
+
|
34
|
+
### Multithreading mode
|
35
|
+
|
36
|
+
When running SamplingProf in multithreading environment (e.g. Rails multithreading production environment), you need turn on multithreading mode so that you can profile all requests processing at same time cross threads.
|
37
|
+
|
38
|
+
### output interval
|
39
|
+
|
40
|
+
Output interval controls how frequent SamplingProf should call output handler to flush out cached data.
|
41
|
+
The default value of output interval is depend on the option of multithreading.
|
42
|
+
When multithreading is off, the default value is nil, because single thread mode is more likely only need to do once data output when the profiling finished.
|
43
|
+
|
44
|
+
When multithreading is on, the default value is 60 seconds, means every 60 seconds SamplingProf will call output handler once to flush out data and restart to cumulate data.
|
45
|
+
|
46
|
+
Output data format
|
47
|
+
---------------
|
48
|
+
|
49
|
+
Output data is divided into a number of chunks. Chunks are separated by 2 "\n" chars.
|
50
|
+
|
51
|
+
List of chunks in order:
|
52
|
+
|
53
|
+
1. runtime
|
54
|
+
2. call element id map
|
55
|
+
3. counts
|
56
|
+
4. call graph
|
57
|
+
|
58
|
+
### runtime chunk
|
59
|
+
|
60
|
+
A number represents time of collecting data.
|
61
|
+
It should be only one line.
|
62
|
+
The time unit is ms.
|
63
|
+
Runtime can be used to compute an estimated runtime of a call element.
|
64
|
+
|
65
|
+
### call element id map
|
66
|
+
|
67
|
+
For storage efficiency, we build this map for counts and call graph chunks to use id instead of a call element string.
|
68
|
+
One line one call element string and its id, separated by a comma.
|
69
|
+
|
70
|
+
#### call element format
|
71
|
+
|
72
|
+
A call element represents a line of code while program running. It has 3 components:
|
73
|
+
|
74
|
+
1. file path
|
75
|
+
2. line number
|
76
|
+
3. method name
|
77
|
+
|
78
|
+
A call element string is a join of 3 components with char ":", for example: ./lib/sampling_prof.rb:5:initialize
|
79
|
+
|
80
|
+
### counts
|
81
|
+
|
82
|
+
SamplingProf collects count of each call element at runtime. There are 2 type of count:
|
83
|
+
|
84
|
+
1. self count
|
85
|
+
2. total count
|
86
|
+
|
87
|
+
Same with call element id map, we use comma to separate data, and one line represents one call element data.
|
88
|
+
Here we use call element id instead of call element string to reference the call element.
|
89
|
+
The line looks like this: <call element id>,<self count>,<total count>
|
90
|
+
|
91
|
+
### call graph
|
92
|
+
|
93
|
+
SamplingProf collects counts of function calls. One function call is A call element calls B call element, and B call element calls A call element is considered as another function call.
|
94
|
+
|
95
|
+
The call graph stores the counts of function calls.
|
96
|
+
Every line is one function call data.
|
97
|
+
the line looks like this: <call element id1>,<call element id2>,<count>
|
98
|
+
|
99
|
+
Direct recursive calls are recorded as: <call element id1>,<call element id1>,<count>
|
100
|
+
|
101
|
+
Indirect recursive calls are ignored as function call only have direct call info. Hence the data maybe odd when there are indirect recursive calls.
|
@@ -8,10 +8,15 @@ class SamplingProf
|
|
8
8
|
@call_graph = Hash.new{|h,k| h[k] = 0}
|
9
9
|
@nodes = {}
|
10
10
|
@threads = threads
|
11
|
+
@start_at = Time.now
|
12
|
+
end
|
13
|
+
|
14
|
+
def runtime
|
15
|
+
Time.now - @start_at
|
11
16
|
end
|
12
17
|
|
13
18
|
def result
|
14
|
-
ret = []
|
19
|
+
ret = [runtime * 1000]
|
15
20
|
ret << @nodes.map {|node| node.join(',')}.join("\n")
|
16
21
|
ret << @samples.map {|count| count.flatten.join(',')}.join("\n")
|
17
22
|
ret << @call_graph.map {|v| v.flatten.join(',')}.join("\n")
|
@@ -92,11 +97,10 @@ class SamplingProf
|
|
92
97
|
@sampling_thread ||= Thread.start do
|
93
98
|
loop do
|
94
99
|
sampling = Sampling.new(@threads)
|
95
|
-
start_time = Time.now
|
96
100
|
loop do
|
97
101
|
break unless @running
|
98
102
|
if @multithreading
|
99
|
-
break if output_interval <
|
103
|
+
break if output_interval < sampling.runtime
|
100
104
|
end
|
101
105
|
sampling.process
|
102
106
|
sleep @sampling_interval
|
data/lib/sampling_prof.jar
CHANGED
Binary file
|
data/lib/sampling_prof.rb
CHANGED
@@ -46,7 +46,7 @@ class SamplingProf
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def report(type, output=$stdout)
|
49
|
-
nodes, counts, call_graph = File.read(output_file).split("\n\n")
|
49
|
+
runtime, nodes, counts, call_graph = File.read(output_file).split("\n\n")
|
50
50
|
nodes = nodes.split("\n").inject({}) do |ret, l|
|
51
51
|
n, i = l.split(',')
|
52
52
|
ret[i.to_i] = n
|
@@ -58,6 +58,7 @@ class SamplingProf
|
|
58
58
|
end
|
59
59
|
total_samples, report = flat_report(nodes, counts)
|
60
60
|
|
61
|
+
output.puts "runtime: #{runtime.to_f/1000} secs"
|
61
62
|
output.puts "total samples: #{total_samples}"
|
62
63
|
output.puts "self\t%\ttotal\t%\tname"
|
63
64
|
report.first(20).each do |v|
|
metadata
CHANGED
@@ -1,70 +1,69 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sampling_prof
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
7
|
-
|
6
|
+
authors:
|
7
|
+
- Xiao Li
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
11
|
+
date: 2014-03-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake-compiler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.2
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.9'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.2
|
27
33
|
description: |
|
28
34
|
SamplingProf is a profiling tool that operates by sampling your running thread stacktrace. The result is statistical approximation, but it allows your code to run near full speed
|
29
|
-
|
30
|
-
|
31
|
-
- swing1979@gmail.com
|
35
|
+
email:
|
36
|
+
- swing1979@gmail.com
|
32
37
|
executables: []
|
33
|
-
|
34
38
|
extensions: []
|
35
|
-
|
36
39
|
extra_rdoc_files: []
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
- lib/sampling_prof/internal.rb
|
40
|
+
files:
|
41
|
+
- README.md
|
42
|
+
- lib/sampling_prof.jar
|
43
|
+
- lib/sampling_prof.rb
|
44
|
+
- lib/sampling_prof/internal.rb
|
43
45
|
homepage: https://github.com/xli/sampling_prof
|
44
|
-
licenses:
|
45
|
-
|
46
|
+
licenses:
|
47
|
+
- MIT
|
46
48
|
metadata: {}
|
47
|
-
|
48
49
|
post_install_message:
|
49
50
|
rdoc_options: []
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
62
63
|
requirements: []
|
63
|
-
|
64
64
|
rubyforge_project:
|
65
|
-
rubygems_version: 2.
|
65
|
+
rubygems_version: 2.2.0
|
66
66
|
signing_key:
|
67
67
|
specification_version: 4
|
68
68
|
summary: Simple sampling profiler for ruby
|
69
69
|
test_files: []
|
70
|
-
|