ruby-prof 0.18.0 → 1.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 +4 -4
- data/CHANGES +23 -0
- data/LICENSE +2 -2
- data/README.rdoc +1 -483
- data/Rakefile +3 -6
- data/bin/ruby-prof +65 -30
- data/ext/ruby_prof/extconf.rb +6 -38
- data/ext/ruby_prof/rp_allocation.c +292 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_info.c +137 -279
- data/ext/ruby_prof/rp_call_info.h +16 -34
- data/ext/ruby_prof/rp_measure_allocations.c +25 -49
- data/ext/ruby_prof/rp_measure_memory.c +21 -56
- data/ext/ruby_prof/rp_measure_process_time.c +28 -36
- data/ext/ruby_prof/rp_measure_wall_time.c +36 -19
- data/ext/ruby_prof/rp_measurement.c +236 -0
- data/ext/ruby_prof/rp_measurement.h +49 -0
- data/ext/ruby_prof/rp_method.c +395 -383
- data/ext/ruby_prof/rp_method.h +34 -39
- data/ext/ruby_prof/rp_profile.c +881 -0
- data/ext/ruby_prof/rp_profile.h +36 -0
- data/ext/ruby_prof/rp_stack.c +103 -80
- data/ext/ruby_prof/rp_stack.h +5 -12
- data/ext/ruby_prof/rp_thread.c +149 -88
- data/ext/ruby_prof/rp_thread.h +15 -6
- data/ext/ruby_prof/ruby_prof.c +11 -757
- data/ext/ruby_prof/ruby_prof.h +4 -47
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +10 -8
- data/lib/ruby-prof.rb +2 -17
- data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
- data/lib/ruby-prof/call_info.rb +35 -93
- data/lib/ruby-prof/call_info_visitor.rb +19 -21
- data/lib/ruby-prof/compatibility.rb +37 -107
- data/lib/ruby-prof/exclude_common_methods.rb +198 -0
- data/lib/ruby-prof/measurement.rb +14 -0
- data/lib/ruby-prof/method_info.rb +52 -83
- data/lib/ruby-prof/printers/abstract_printer.rb +66 -52
- data/lib/ruby-prof/printers/call_info_printer.rb +13 -3
- data/lib/ruby-prof/printers/call_stack_printer.rb +32 -28
- data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
- data/lib/ruby-prof/printers/dot_printer.rb +5 -5
- data/lib/ruby-prof/printers/flat_printer.rb +6 -24
- data/lib/ruby-prof/printers/graph_html_printer.rb +7 -192
- data/lib/ruby-prof/printers/graph_printer.rb +13 -15
- data/lib/ruby-prof/printers/multi_printer.rb +66 -23
- data/lib/ruby-prof/profile.rb +10 -3
- data/lib/ruby-prof/rack.rb +0 -3
- data/lib/ruby-prof/thread.rb +12 -12
- data/lib/ruby-prof/version.rb +1 -1
- data/ruby-prof.gemspec +2 -2
- data/test/abstract_printer_test.rb +0 -27
- data/test/alias_test.rb +129 -0
- data/test/basic_test.rb +41 -40
- data/test/call_info_visitor_test.rb +3 -3
- data/test/dynamic_method_test.rb +0 -2
- data/test/line_number_test.rb +120 -39
- data/test/marshal_test.rb +119 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +371 -12
- data/test/measure_allocations_trace_test.rb +385 -0
- data/test/measure_memory_trace_test.rb +756 -0
- data/test/measure_process_time_test.rb +821 -33
- data/test/measure_times.rb +54 -0
- data/test/measure_wall_time_test.rb +349 -145
- data/test/multi_printer_test.rb +1 -34
- data/test/parser_timings.rb +24 -0
- data/test/pause_resume_test.rb +5 -5
- data/test/prime.rb +2 -0
- data/test/printer_call_tree_test.rb +31 -0
- data/test/printer_flat_test.rb +68 -0
- data/test/printer_graph_html_test.rb +60 -0
- data/test/printer_graph_test.rb +41 -0
- data/test/printers_test.rb +32 -166
- data/test/printing_recursive_graph_test.rb +26 -72
- data/test/recursive_test.rb +72 -77
- data/test/stack_printer_test.rb +2 -15
- data/test/start_stop_test.rb +22 -25
- data/test/test_helper.rb +5 -248
- data/test/thread_test.rb +11 -54
- data/test/unique_call_path_test.rb +16 -28
- data/test/yarv_test.rb +1 -0
- metadata +24 -34
- data/examples/flat.txt +0 -50
- data/examples/graph.dot +0 -84
- data/examples/graph.html +0 -823
- data/examples/graph.txt +0 -139
- data/examples/multi.flat.txt +0 -23
- data/examples/multi.graph.html +0 -760
- data/examples/multi.grind.dat +0 -114
- data/examples/multi.stack.html +0 -547
- data/examples/stack.html +0 -547
- data/ext/ruby_prof/rp_measure.c +0 -40
- data/ext/ruby_prof/rp_measure.h +0 -45
- data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
- data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
- data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
- data/lib/ruby-prof/aggregate_call_info.rb +0 -76
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
- data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
- data/test/aggregate_test.rb +0 -136
- data/test/block_test.rb +0 -74
- data/test/call_info_test.rb +0 -78
- data/test/fiber_test.rb +0 -79
- data/test/issue137_test.rb +0 -63
- data/test/measure_cpu_time_test.rb +0 -212
- data/test/measure_gc_runs_test.rb +0 -32
- data/test/measure_gc_time_test.rb +0 -36
- data/test/measure_memory_test.rb +0 -33
- data/test/method_elimination_test.rb +0 -84
- data/test/module_test.rb +0 -45
- data/test/stack_test.rb +0 -138
data/ext/ruby_prof/ruby_prof.h
CHANGED
@@ -5,56 +5,13 @@
|
|
5
5
|
#define __RUBY_PROF_H__
|
6
6
|
|
7
7
|
#include <ruby.h>
|
8
|
+
#include <ruby/debug.h>
|
8
9
|
#include <stdio.h>
|
9
|
-
|
10
|
-
#if RUBY_PROF_RUBY_VERSION == 10806
|
11
|
-
# error 1.8.6 is not supported. Please upgrade to 1.9.3 or higher.
|
12
|
-
#endif
|
13
|
-
|
14
|
-
#if RUBY_PROF_RUBY_VERSION == 10807
|
15
|
-
# error 1.8.7 is not supported. Please upgrade to 1.9.3 or higher.
|
16
|
-
#endif
|
17
|
-
|
18
|
-
#if RUBY_PROF_RUBY_VERSION == 10900
|
19
|
-
# error 1.9.0 is not supported. Please upgrade to 1.9.3 or higher.
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#if RUBY_PROF_RUBY_VERSION == 10901
|
23
|
-
# error 1.9.1 is not supported. Please upgrade to 1.9.3 or higher.
|
24
|
-
#endif
|
25
|
-
|
26
|
-
#if RUBY_PROF_RUBY_VERSION == 10902
|
27
|
-
# error 1.9.2 is not supported. Please upgrade to 1.9.3 or higher.
|
28
|
-
#endif
|
29
|
-
|
30
|
-
#include "rp_measure.h"
|
31
|
-
#include "rp_method.h"
|
32
|
-
#include "rp_call_info.h"
|
33
|
-
#include "rp_stack.h"
|
34
|
-
#include "rp_thread.h"
|
10
|
+
#include <stdbool.h>
|
35
11
|
|
36
12
|
extern VALUE mProf;
|
37
|
-
extern VALUE cProfile;
|
38
|
-
|
39
|
-
void method_key(prof_method_key_t* key, VALUE klass, ID mid);
|
40
|
-
|
41
|
-
typedef struct
|
42
|
-
{
|
43
|
-
VALUE running;
|
44
|
-
VALUE paused;
|
45
|
-
|
46
|
-
prof_measurer_t* measurer;
|
47
|
-
VALUE threads;
|
48
|
-
|
49
|
-
st_table* threads_tbl;
|
50
|
-
st_table* exclude_threads_tbl;
|
51
|
-
st_table* include_threads_tbl;
|
52
|
-
st_table* exclude_methods_tbl;
|
53
|
-
thread_data_t* last_thread_data;
|
54
|
-
double measurement_at_pause_resume;
|
55
|
-
int merge_fibers;
|
56
|
-
int allow_exceptions;
|
57
|
-
} prof_profile_t;
|
58
13
|
|
14
|
+
// This method is not exposed in Ruby header files - at least not as of Ruby 2.6.3 :(
|
15
|
+
extern size_t rb_obj_memsize_of(VALUE);
|
59
16
|
|
60
17
|
#endif //__RUBY_PROF_H__
|
@@ -64,7 +64,7 @@
|
|
64
64
|
</PropertyGroup>
|
65
65
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
66
66
|
<TargetExt>.so</TargetExt>
|
67
|
-
<OutDir
|
67
|
+
<OutDir>..\</OutDir>
|
68
68
|
</PropertyGroup>
|
69
69
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
70
70
|
<ClCompile>
|
@@ -102,35 +102,37 @@
|
|
102
102
|
</ItemDefinitionGroup>
|
103
103
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
104
104
|
<ClCompile>
|
105
|
-
<AdditionalIncludeDirectories>C:\msys64\usr\local\
|
105
|
+
<AdditionalIncludeDirectories>C:\msys64\usr\local\ruby-2.6.3vc\include\ruby-2.6.0\x64-mswin64_140;C:\msys64\usr\local\ruby-2.6.3vc\include\ruby-2.6.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
106
106
|
<Optimization>Disabled</Optimization>
|
107
|
+
<PreprocessorDefinitions>HAVE_RB_TRACEARG_CALLEE_ID;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
107
108
|
</ClCompile>
|
108
109
|
<Link>
|
109
|
-
<AdditionalLibraryDirectories>C:\msys64\usr\local\
|
110
|
+
<AdditionalLibraryDirectories>C:\msys64\usr\local\ruby-2.6.3vc\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
110
111
|
<AdditionalDependencies>x64-vcruntime140-ruby260.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
111
112
|
<ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
|
112
113
|
</Link>
|
113
114
|
</ItemDefinitionGroup>
|
114
115
|
<ItemGroup>
|
116
|
+
<ClInclude Include="..\rp_allocation.h" />
|
115
117
|
<ClInclude Include="..\rp_call_info.h" />
|
116
|
-
<ClInclude Include="..\
|
118
|
+
<ClInclude Include="..\rp_measurement.h" />
|
117
119
|
<ClInclude Include="..\rp_method.h" />
|
120
|
+
<ClInclude Include="..\rp_profile.h" />
|
118
121
|
<ClInclude Include="..\rp_stack.h" />
|
119
122
|
<ClInclude Include="..\rp_thread.h" />
|
120
123
|
<ClInclude Include="..\ruby_prof.h" />
|
121
124
|
<ClInclude Include="..\version.h" />
|
122
125
|
</ItemGroup>
|
123
126
|
<ItemGroup>
|
127
|
+
<ClCompile Include="..\rp_allocation.c" />
|
124
128
|
<ClCompile Include="..\rp_call_info.c" />
|
125
|
-
<ClCompile Include="..\
|
129
|
+
<ClCompile Include="..\rp_measurement.c" />
|
126
130
|
<ClCompile Include="..\rp_measure_allocations.c" />
|
127
|
-
<ClCompile Include="..\rp_measure_cpu_time.c" />
|
128
|
-
<ClCompile Include="..\rp_measure_gc_runs.c" />
|
129
|
-
<ClCompile Include="..\rp_measure_gc_time.c" />
|
130
131
|
<ClCompile Include="..\rp_measure_memory.c" />
|
131
132
|
<ClCompile Include="..\rp_measure_process_time.c" />
|
132
133
|
<ClCompile Include="..\rp_measure_wall_time.c" />
|
133
134
|
<ClCompile Include="..\rp_method.c" />
|
135
|
+
<ClCompile Include="..\rp_profile.c" />
|
134
136
|
<ClCompile Include="..\rp_stack.c" />
|
135
137
|
<ClCompile Include="..\rp_thread.c" />
|
136
138
|
<ClCompile Include="..\ruby_prof.c" />
|
data/lib/ruby-prof.rb
CHANGED
@@ -8,19 +8,10 @@ rescue LoadError
|
|
8
8
|
require "ruby_prof.so"
|
9
9
|
end
|
10
10
|
|
11
|
-
module RubyProf
|
12
|
-
module DeprecationWarnings
|
13
|
-
def deprecation_warning(feature, recommendation = nil)
|
14
|
-
$stderr.puts "DEPRECATION WARNING: #{feature}"
|
15
|
-
$stderr.puts recommendation unless recommendation.nil?
|
16
|
-
end
|
17
|
-
end
|
18
|
-
extend DeprecationWarnings
|
19
|
-
end
|
20
|
-
|
21
11
|
require 'ruby-prof/version'
|
22
12
|
require 'ruby-prof/call_info'
|
23
13
|
require 'ruby-prof/compatibility'
|
14
|
+
require 'ruby-prof/measurement'
|
24
15
|
require 'ruby-prof/method_info'
|
25
16
|
require 'ruby-prof/profile'
|
26
17
|
require 'ruby-prof/rack'
|
@@ -36,29 +27,23 @@ module RubyProf
|
|
36
27
|
autoload :CallTreePrinter, 'ruby-prof/printers/call_tree_printer'
|
37
28
|
autoload :DotPrinter, 'ruby-prof/printers/dot_printer'
|
38
29
|
autoload :FlatPrinter, 'ruby-prof/printers/flat_printer'
|
39
|
-
autoload :FlatPrinterWithLineNumbers, 'ruby-prof/printers/flat_printer_with_line_numbers'
|
40
30
|
autoload :GraphHtmlPrinter, 'ruby-prof/printers/graph_html_printer'
|
41
31
|
autoload :GraphPrinter, 'ruby-prof/printers/graph_printer'
|
42
32
|
autoload :MultiPrinter, 'ruby-prof/printers/multi_printer'
|
43
33
|
|
34
|
+
# :nodoc:
|
44
35
|
# Checks if the user specified the clock mode via
|
45
36
|
# the RUBY_PROF_MEASURE_MODE environment variable
|
46
37
|
def self.figure_measure_mode
|
47
38
|
case ENV["RUBY_PROF_MEASURE_MODE"]
|
48
39
|
when "wall", "wall_time"
|
49
40
|
RubyProf.measure_mode = RubyProf::WALL_TIME
|
50
|
-
when "cpu", "cpu_time"
|
51
|
-
RubyProf.measure_mode = RubyProf::CPU_TIME
|
52
41
|
when "allocations"
|
53
42
|
RubyProf.measure_mode = RubyProf::ALLOCATIONS
|
54
43
|
when "memory"
|
55
44
|
RubyProf.measure_mode = RubyProf::MEMORY
|
56
45
|
when "process", "process_time"
|
57
46
|
RubyProf.measure_mode = RubyProf::PROCESS_TIME
|
58
|
-
when "gc_time"
|
59
|
-
RubyProf.measure_mode = RubyProf::GC_TIME
|
60
|
-
when "gc_runs"
|
61
|
-
RubyProf.measure_mode = RubyProf::GC_RUNS
|
62
47
|
else
|
63
48
|
# the default is defined in the measure_mode reader
|
64
49
|
end
|
@@ -0,0 +1,356 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<style media="all" type="text/css">
|
5
|
+
body {
|
6
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
7
|
+
background-color: #F5F7FB;
|
8
|
+
margin: 0;
|
9
|
+
padding: 0;
|
10
|
+
font-size: 16px;
|
11
|
+
}
|
12
|
+
|
13
|
+
table {
|
14
|
+
border-collapse: collapse;
|
15
|
+
/* border: 1px solid #E1E3E7; */
|
16
|
+
border: 1px solid #F3F9FE;
|
17
|
+
font-size: 14px;
|
18
|
+
line-height: normal;
|
19
|
+
width: 100%;
|
20
|
+
}
|
21
|
+
|
22
|
+
table:empty {
|
23
|
+
display: none;
|
24
|
+
}
|
25
|
+
|
26
|
+
th:first-child {
|
27
|
+
border-left: 0;
|
28
|
+
}
|
29
|
+
|
30
|
+
th {
|
31
|
+
text-align: center;
|
32
|
+
background: #F3F9FE;
|
33
|
+
padding: 1rem;
|
34
|
+
/* border-left: 1px solid #E1E3E7; */
|
35
|
+
text-transform: uppercase;
|
36
|
+
font-size: 13px;
|
37
|
+
letter-spacing: 1px;
|
38
|
+
}
|
39
|
+
|
40
|
+
tr.break td {
|
41
|
+
border: 0;
|
42
|
+
border-top: 1px solid #BDC3DD;
|
43
|
+
padding: 0;
|
44
|
+
margin: 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
tr.method td {
|
48
|
+
font-weight: bold;
|
49
|
+
}
|
50
|
+
|
51
|
+
td {
|
52
|
+
padding: 0.5em;
|
53
|
+
}
|
54
|
+
|
55
|
+
td:first-child {
|
56
|
+
width: 190px;
|
57
|
+
}
|
58
|
+
|
59
|
+
tr > td > table {
|
60
|
+
box-shadow: 0px -2px 1px #F9FAFB, 0px 1px 1px #E4EEEE, 0px 1px 2px #EEF3F8;
|
61
|
+
border-radius: 2px;
|
62
|
+
overflow: hidden;
|
63
|
+
}
|
64
|
+
|
65
|
+
tr.break + tr > td.method_name {
|
66
|
+
font-weight: bold;
|
67
|
+
}
|
68
|
+
|
69
|
+
td {
|
70
|
+
/* I'm removing this border because I think it looks way cleaner without it but feel free to add it if you feel it's necessary */
|
71
|
+
/* border-left: 1px solid #E1E3E7; */
|
72
|
+
text-align: center;
|
73
|
+
}
|
74
|
+
|
75
|
+
a {
|
76
|
+
text-decoration: none;
|
77
|
+
}
|
78
|
+
|
79
|
+
.method_name {
|
80
|
+
text-align: left;
|
81
|
+
}
|
82
|
+
|
83
|
+
tfoot td {
|
84
|
+
text-align: left;
|
85
|
+
}
|
86
|
+
|
87
|
+
.report-header {
|
88
|
+
background-color: #0D2483;
|
89
|
+
color: white;
|
90
|
+
padding: 1.5rem 2rem;
|
91
|
+
}
|
92
|
+
|
93
|
+
.report-header > div {
|
94
|
+
display: flex;
|
95
|
+
flex-direction: row;
|
96
|
+
align-items: center;
|
97
|
+
}
|
98
|
+
|
99
|
+
.report-header h1 {
|
100
|
+
margin-bottom: 0;
|
101
|
+
}
|
102
|
+
|
103
|
+
h1, h2, h3, h4, h5, h6 {
|
104
|
+
margin-top: 0;
|
105
|
+
margin-bottom: 0.5rem;
|
106
|
+
}
|
107
|
+
|
108
|
+
h6 {
|
109
|
+
font-size: 0.75rem;
|
110
|
+
text-transform: uppercase;
|
111
|
+
letter-spacing: 1.5px;
|
112
|
+
color: rgba(255, 255, 255, 0.6);
|
113
|
+
}
|
114
|
+
|
115
|
+
.table-header {
|
116
|
+
padding: 3rem 0 1rem;
|
117
|
+
}
|
118
|
+
|
119
|
+
.table-wrapper {
|
120
|
+
margin: 1rem auto;
|
121
|
+
max-width: 1440px;
|
122
|
+
padding: 4rem 5rem;
|
123
|
+
background: white;
|
124
|
+
border-radius: 0.5rem;
|
125
|
+
}
|
126
|
+
|
127
|
+
.center {
|
128
|
+
max-width: 1440px;
|
129
|
+
margin: 0 auto;
|
130
|
+
}
|
131
|
+
|
132
|
+
.layout-right {
|
133
|
+
margin-left: auto;
|
134
|
+
}
|
135
|
+
|
136
|
+
.text-right {
|
137
|
+
display: flex;
|
138
|
+
align-items: flex-end;
|
139
|
+
flex-direction: column;
|
140
|
+
}
|
141
|
+
|
142
|
+
.timestamp {
|
143
|
+
font-size: 12px;
|
144
|
+
margin-bottom: 1rem;
|
145
|
+
color: rgba(255, 255, 255, 0.6);
|
146
|
+
}
|
147
|
+
|
148
|
+
.logo {
|
149
|
+
width: 140px;
|
150
|
+
height: 30px;
|
151
|
+
opacity: 0.5;
|
152
|
+
background-repeat: no-repeat;
|
153
|
+
background-image: url("data:image/svg+xml,%3Csvg id='Layer_1' data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 190 41'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23fff%7D%3C/style%3E%3C/defs%3E%3Cpath class='cls-1' d='M63.49 16.74c0-1.37-.91-2-2.26-2h-3.38v3.93h3.58c1.24.01 2.06-.56 2.06-1.93zM110.43 14.75h-3.6v5h3.6a2.32 2.32 0 0 0 2.5-2.49 2.34 2.34 0 0 0-2.5-2.51zM128.77 14.75h-3.53v4.94h3.53a2.28 2.28 0 0 0 2.47-2.45 2.3 2.3 0 0 0-2.47-2.49zM61.81 21.83h-4v4.32h3.91c1.44 0 2.45-.62 2.45-2.14s-.99-2.18-2.36-2.18zM21 14.75h-3.57v4.94H21a2.28 2.28 0 0 0 2.47-2.45A2.3 2.3 0 0 0 21 14.75z'/%3E%3Cpath class='cls-1' d='M184 .44H5.87A4.93 4.93 0 0 0 .94 5.37V35.5a4.94 4.94 0 0 0 4.93 4.94H184a4.94 4.94 0 0 0 4.94-4.94V5.37A4.94 4.94 0 0 0 184 .44zm-34.38 10.78c4.79 0 8.46 2.89 9.18 7.54h-3.86a5.48 5.48 0 0 0-10.68 0h-3.83c.71-4.65 4.36-7.54 9.19-7.54zM24 29.44L20.46 23h-3v6.46h-3.72v-18h7.68c3.41 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.82 7.06zm24.31-7.3c0 4.8-2.92 7.56-7.63 7.56S33 26.94 33 22.14V11.48h3.69v10.61c0 2.81 1.37 4.32 4 4.32s3.94-1.51 3.94-4.32V11.48h3.69zm13.92 7.3h-8v-18h7.52c3.24 0 5.59 1.61 5.59 5A4 4 0 0 1 65.51 20 4.22 4.22 0 0 1 68 24.21c0 3.43-2.4 5.23-5.81 5.23zm19.66-6.92v6.92h-3.7v-6.92l-6.81-11h4.29L80 18.85l4.34-7.37h4.32zm16-.5h-7.62v-3.26h7.59zm13 1h-4v6.39h-3.72v-18h7.77c3.41 0 5.79 2.09 5.79 5.79s-2.41 5.85-5.82 5.85zm20.86 6.39L128.26 23h-3v6.46h-3.72v-18h7.69c3.4 0 5.78 2.07 5.78 5.76a5.34 5.34 0 0 1-2.88 5.14l3.87 7.08zm17.85.26c-4.88 0-8.55-2.95-9.21-7.68h3.81A5.49 5.49 0 0 0 155 22h3.84c-.69 4.75-4.38 7.7-9.22 7.7zm18.4-.23h-3.72v-3.7H168zm6.36-7.54h-10.05v-3.26h10.08zm1.44-7.16h-11.49v-3.26h11.52z'/%3E%3C/svg%3E");
|
154
|
+
}
|
155
|
+
</style>
|
156
|
+
</head>
|
157
|
+
<body>
|
158
|
+
<div class="report-header">
|
159
|
+
<div class="center">
|
160
|
+
<div class="layout-left">
|
161
|
+
<h6>Profile Report</h6>
|
162
|
+
<h1><%= @result.measure_mode_string.capitalize %></h1>
|
163
|
+
</div>
|
164
|
+
<div class="layout-right text-right">
|
165
|
+
<div class="timestamp"><%= Time.now.strftime(self.time_format) %></div>
|
166
|
+
<div class="logo"></div>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
</div>
|
170
|
+
<div class="table-wrapper">
|
171
|
+
<table>
|
172
|
+
<tr>
|
173
|
+
<th>Thread ID</th>
|
174
|
+
<th>Fiber ID</th>
|
175
|
+
<th>Total</th>
|
176
|
+
</tr>
|
177
|
+
<% for thread in @result.threads %>
|
178
|
+
<tr>
|
179
|
+
<td><%= thread.id %></td>
|
180
|
+
<td><a href="#<%= thread.fiber_id %>"><%= thread.fiber_id %></a></td>
|
181
|
+
<td><%= thread.total_time %></td>
|
182
|
+
</tr>
|
183
|
+
<% end %>
|
184
|
+
</table>
|
185
|
+
|
186
|
+
<!-- Methods Tables -->
|
187
|
+
<%
|
188
|
+
for thread in @result.threads
|
189
|
+
methods = thread.methods
|
190
|
+
total_time = thread.total_time
|
191
|
+
%>
|
192
|
+
<h2><a name="<%= thread.fiber_id %>">Thread <%= thread.id %>, Fiber: <%= thread.fiber_id %></a></h2>
|
193
|
+
<table>
|
194
|
+
<thead>
|
195
|
+
<tr>
|
196
|
+
<th>%Total</th>
|
197
|
+
<th>%Self</th>
|
198
|
+
<th>Total</th>
|
199
|
+
<th>Self</th>
|
200
|
+
<th>Wait</th>
|
201
|
+
<th>Child</th>
|
202
|
+
<th>Calls</th>
|
203
|
+
<th class="method_name">Name</th>
|
204
|
+
<% if @result.track_allocations? %>
|
205
|
+
<th>Allocations</th>
|
206
|
+
<% end %>
|
207
|
+
<th>Line</th>
|
208
|
+
</tr>
|
209
|
+
</thead>
|
210
|
+
<tbody>
|
211
|
+
<% min_time = @options[:min_time] || (@options[:nonzero] ? 0.005 : nil)
|
212
|
+
sorted_methods = sort_method ? methods.sort_by(&sort_method) : methods.sort
|
213
|
+
sorted_methods.reverse_each do |method|
|
214
|
+
total_percentage = (method.total_time/total_time) * 100
|
215
|
+
next if total_percentage < min_percent
|
216
|
+
next if min_time && method.total_time < min_time
|
217
|
+
self_percentage = (method.self_time/total_time) * 100 %>
|
218
|
+
|
219
|
+
<!-- Parents -->
|
220
|
+
<% for caller in method.callers.sort
|
221
|
+
next if method.root?
|
222
|
+
next if min_time && caller.total_time < min_time %>
|
223
|
+
<tr>
|
224
|
+
<td> </td>
|
225
|
+
<td> </td>
|
226
|
+
<td><%= sprintf("%.2f", caller.total_time) %></td>
|
227
|
+
<td><%= sprintf("%.2f", caller.self_time) %></td>
|
228
|
+
<td><%= sprintf("%.2f", caller.wait_time) %></td>
|
229
|
+
<td><%= sprintf("%.2f", caller.children_time) %></td>
|
230
|
+
<td><%= "#{caller.called}/#{method.called}" %></td>
|
231
|
+
<td class="method_name"><%= create_link(thread, total_time, caller.parent) %></td>
|
232
|
+
<% if @result.track_allocations? %>
|
233
|
+
<td>-</td>
|
234
|
+
<% end %>
|
235
|
+
<td><%= if caller.parent.source_file
|
236
|
+
file_link(caller.parent.source_file, caller.line)
|
237
|
+
end %></td>
|
238
|
+
</tr>
|
239
|
+
<% end %>
|
240
|
+
<tr class="method">
|
241
|
+
<td><%= sprintf("%.2f%%", total_percentage) %></td>
|
242
|
+
<td><%= sprintf("%.2f%%", self_percentage) %></td>
|
243
|
+
<td><%= sprintf("%.2f", method.total_time) %></td>
|
244
|
+
<td><%= sprintf("%.2f", method.self_time) %></td>
|
245
|
+
<td><%= sprintf("%.2f", method.wait_time) %></td>
|
246
|
+
<td><%= sprintf("%.2f", method.children_time) %></td>
|
247
|
+
<td><%= sprintf("%i", method.called) %></td>
|
248
|
+
<td class="method_name">
|
249
|
+
<a name="<%= method_href(thread, method) %>">
|
250
|
+
<%= method.recursive? ? "*" : " " %><%= h method.full_name %>
|
251
|
+
</a>
|
252
|
+
</td>
|
253
|
+
|
254
|
+
<% if @result.track_allocations? %>
|
255
|
+
<td>
|
256
|
+
<% count = method.allocations.reduce(0) do |size, allocation|
|
257
|
+
size += allocation.count
|
258
|
+
end %>
|
259
|
+
<% if count > 0 %>
|
260
|
+
<a class="allocations" href="#<%= method_href(thread, method) %>_allocations" %><%= count %></a>
|
261
|
+
<% else %>
|
262
|
+
0
|
263
|
+
<% end %>
|
264
|
+
</td>
|
265
|
+
<% end %>
|
266
|
+
|
267
|
+
<td><%= if method.source_file
|
268
|
+
file_link(method.source_file, method.line)
|
269
|
+
end %></td>
|
270
|
+
</tr>
|
271
|
+
|
272
|
+
<% if @result.track_allocations? %>
|
273
|
+
<tr>
|
274
|
+
<td colspan="10">
|
275
|
+
<table id="<%= method_href(thread, method) %>_allocations" class="allocations" style="display: none">
|
276
|
+
<% for allocation in method.allocations %>
|
277
|
+
<tr>
|
278
|
+
<td>
|
279
|
+
<%= allocation.klass_name %>
|
280
|
+
</td>
|
281
|
+
<td>
|
282
|
+
<%= "#{allocation.count} (#{allocation.memory} Bytes)" %>
|
283
|
+
</td>
|
284
|
+
<td>
|
285
|
+
<%= "#{allocation.source_file}:#{allocation.line}" %>
|
286
|
+
</td>
|
287
|
+
</tr>
|
288
|
+
<% end %>
|
289
|
+
</table>
|
290
|
+
|
291
|
+
</td>
|
292
|
+
</tr>
|
293
|
+
<% end %>
|
294
|
+
|
295
|
+
<!-- Children -->
|
296
|
+
<% for callee in method.callees.sort_by(&:total_time).reverse
|
297
|
+
next if min_time && callee.total_time < min_time %>
|
298
|
+
<tr>
|
299
|
+
<td> </td>
|
300
|
+
<td> </td>
|
301
|
+
<td><%= sprintf("%.2f", callee.total_time) %></td>
|
302
|
+
<td><%= sprintf("%.2f", callee.self_time) %></td>
|
303
|
+
<td><%= sprintf("%.2f", callee.wait_time) %></td>
|
304
|
+
<td><%= sprintf("%.2f", callee.children_time) %></td>
|
305
|
+
<td><%= "#{callee.called}/#{callee.target.called}" %></td>
|
306
|
+
<td class="method_name"><%= create_link(thread, total_time, callee.target) %></td>
|
307
|
+
<% if @result.track_allocations? %>
|
308
|
+
<td>-</td>
|
309
|
+
<% end %>
|
310
|
+
<td><%= file_link(callee.source_file, callee.line) %>
|
311
|
+
</tr>
|
312
|
+
<% end %>
|
313
|
+
|
314
|
+
<!-- Create divider row -->
|
315
|
+
<tr class="break">
|
316
|
+
<td colspan="10"></td>
|
317
|
+
</tr>
|
318
|
+
<% end %>
|
319
|
+
</tbody>
|
320
|
+
<tfoot>
|
321
|
+
<tr>
|
322
|
+
<td colspan="9">* indicates recursively called methods</td>
|
323
|
+
</tr>
|
324
|
+
</tfoot>
|
325
|
+
</table>
|
326
|
+
<% end %>
|
327
|
+
</div>
|
328
|
+
|
329
|
+
<script type="application/javascript">
|
330
|
+
function toggleAllocations(element)
|
331
|
+
{
|
332
|
+
if (element.style.display == 'none')
|
333
|
+
element.style.display = 'block'
|
334
|
+
else
|
335
|
+
element.style.display = 'none'
|
336
|
+
}
|
337
|
+
|
338
|
+
function onClick(event)
|
339
|
+
{
|
340
|
+
if (event.target.tagName == 'A' && event.target.classList.contains('allocations'))
|
341
|
+
{
|
342
|
+
var url = new URL(event.target.href)
|
343
|
+
var element = document.querySelector(url.hash)
|
344
|
+
toggleAllocations(element)
|
345
|
+
event.preventDefault()
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
window.addEventListener('DOMContentLoaded', function(event)
|
350
|
+
{
|
351
|
+
document.addEventListener('click', onClick)
|
352
|
+
})
|
353
|
+
|
354
|
+
</script>
|
355
|
+
</body>
|
356
|
+
</html>
|