ruby-prof 1.4.2 → 1.4.3

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
2
  SHA256:
3
- metadata.gz: 6e62266e388c4742f279cccfd909bc167b83e2b2bc3438b52254855281ec3b56
4
- data.tar.gz: 4becfdabd8c0453c433f36fcc767a32e5ac50f295c45deaa9b9ed7e09763b8e2
3
+ metadata.gz: d823139ee13d55c54104dd034274b61316a525b54ac3802b90dcb111d8ccb3d2
4
+ data.tar.gz: c9ae3a108bbe1f9559848df06a943c4d42e10e4b62a450f8e0278d796ed90f80
5
5
  SHA512:
6
- metadata.gz: ecdc60504e71f9adc7bcc5df7deb3864e0fad1544cfc57ad225053a205bdb75cad3953a415834761c964e069907e232786f977f667a7492bd7521839a4663bb4
7
- data.tar.gz: d524f3cfa338fb190b362e42d29aaa1b60d1011e84945e73dd6bfc7f5979e0d3fe8702f6135f2c5a3f67ae4dddcd1915e7ddd1db7bab70ee00d22447cb02a398
6
+ metadata.gz: 505e983efedd32bed3cdadff2256e4c9c875551caba829999ec2dd87a36052024612eec9e70ebe586b05b3ee70b95d8c3dba3bd5b14bd01ca1243317a5336313
7
+ data.tar.gz: 9e3430bd9af49f2a045485bc9322f2deabe23bd43575ae00e0718316829d1468492db17476b7a428f6592f7d5fc65ad3f96e68de97a084ff606971ef89d5e14b
data/CHANGES CHANGED
@@ -1,3 +1,16 @@
1
+ 1.4.3 (2021-02-15)
2
+ =====================
3
+ * Remove trailing spaces (sergioro)
4
+ * Enable loading ruby_prof.so from ext directory for development purposes (sergioro)
5
+ * Create temp directory for test output (sergioro)
6
+ * Fix minitest warning about using MT_CPU instead of N (sergioro)
7
+ * Fix minitest warning "Use assert_nil if expecting nil" (sergioro)
8
+ * Fix file permissions (sergioro)
9
+ * Fix failing test by forcing GC to run (Charlie Savage)
10
+ * Switch to GitHub actions (Charlie Savage)
11
+ * Switch to C11 (Charlie Savage)
12
+ * Greatly slim down library size by removing symbols on GCC (Charlie Savage)
13
+
1
14
  1.4.2 (2020-11-3)
2
15
  =====================
3
16
  * Do NOT use Ruby 2.7.0 and 2.7.1 with ruby-prof. A bug in those versions of ruby causes ruby-prof to
data/README.rdoc CHANGED
@@ -1,5 +1,5 @@
1
1
  = ruby-prof
2
2
 
3
- {<img src="https://travis-ci.org/ruby-prof/ruby-prof.png?branch=master" alt="Build Status" />}[https://travis-ci.org/ruby-prof/ruby-prof]
3
+ ![ruby-prof](https://github.com/ruby-prof/ruby-prof/workflows/ruby-prof/badge.svg)
4
4
 
5
5
  For an overview of ruby-prof please see https://ruby-prof.github.io
@@ -1,11 +1,17 @@
1
1
  require "mkmf"
2
2
 
3
- # This function was added in Ruby 2.5, so once Ruby 2.4 is no longer supported this can be removed
4
- have_func('rb_tracearg_callee_id', ["ruby.h"])
3
+ # Let's go with a modern version of C! want to intermix declarations and code (ie, don't define
4
+ # all variables at the top of the method). If using Visual Studio, you'll need 2019 version
5
+ # 16.8 or higher
6
+ if RUBY_PLATFORM =~ /mswin/
7
+ $CFLAGS += ' /std:c11'
8
+ else
9
+ $CFLAGS += ' -std=c11'
10
+ end
5
11
 
6
- # We want to intermix declarations and code (ie, don't define all variables at the top of the method)
7
- unless RUBY_PLATFORM =~ /mswin/
8
- $CFLAGS += ' -std=c99'
12
+ # For gcc add -s to strip symbols, reducing library size from 17MB to 78KB (at least on Windows with mingw64)
13
+ if RUBY_PLATFORM !~ /mswin/
14
+ $LDFLAGS += ' -s'
9
15
  end
10
16
 
11
17
  # And since we are using C99 we want to disable Ruby sending these warnings to gcc
@@ -141,7 +141,7 @@ static const rb_data_type_t allocation_type =
141
141
  },
142
142
  .data = NULL,
143
143
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
144
- };
144
+ };
145
145
 
146
146
  VALUE prof_allocation_wrap(prof_allocation_t* allocation)
147
147
  {
@@ -100,7 +100,7 @@ static const rb_data_type_t measurement_type =
100
100
  },
101
101
  .data = NULL,
102
102
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
103
- };
103
+ };
104
104
 
105
105
  VALUE prof_measurement_wrap(prof_measurement_t* measurement)
106
106
  {
@@ -253,7 +253,7 @@ static const rb_data_type_t method_info_type =
253
253
  },
254
254
  .data = NULL,
255
255
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
256
- };
256
+ };
257
257
 
258
258
  VALUE prof_method_wrap(prof_method_t* method)
259
259
  {
@@ -488,4 +488,4 @@ void rp_init_method_info()
488
488
 
489
489
  rb_define_method(cRpMethodInfo, "_dump_data", prof_method_dump, 0);
490
490
  rb_define_method(cRpMethodInfo, "_load_data", prof_method_load, 1);
491
- }
491
+ }
@@ -9,35 +9,35 @@
9
9
 
10
10
  extern VALUE cRpMethodInfo;
11
11
 
12
- // Source relation bit offsets.
12
+ // Source relation bit offsets.
13
13
  enum {
14
- kModuleIncludee = 0x1, // Included in module
15
- kClassSingleton = 0x2, // Singleton of a class
16
- kModuleSingleton = 0x4, // Singleton of a module
17
- kObjectSingleton = 0x8, // Singleton of an object
18
- kOtherSingleton = 0x10 // Singleton of unkown object
14
+ kModuleIncludee = 0x1, // Included in module
15
+ kClassSingleton = 0x2, // Singleton of a class
16
+ kModuleSingleton = 0x4, // Singleton of a module
17
+ kObjectSingleton = 0x8, // Singleton of an object
18
+ kOtherSingleton = 0x10 // Singleton of unkown object
19
19
  };
20
20
 
21
- // Profiling information for each method.
22
- // Excluded methods have no call_trees, source_klass, or source_file.
21
+ // Profiling information for each method.
22
+ // Excluded methods have no call_trees, source_klass, or source_file.
23
23
  typedef struct prof_method_t
24
24
  {
25
25
  VALUE profile; // Profile this method is associated with - needed for mark phase
26
- struct prof_call_trees_t* call_trees; // Call infos that call this method
27
- st_table* allocations_table; // Tracks object allocations
26
+ struct prof_call_trees_t* call_trees; // Call infos that call this method
27
+ st_table* allocations_table; // Tracks object allocations
28
28
 
29
- st_data_t key; // Table key
30
- unsigned int klass_flags; // Information about the type of class
31
- VALUE klass; // Resolved klass
32
- VALUE klass_name; // Resolved klass name for this method
33
- VALUE method_name; // Resolved method name for this method
29
+ st_data_t key; // Table key
30
+ unsigned int klass_flags; // Information about the type of class
31
+ VALUE klass; // Resolved klass
32
+ VALUE klass_name; // Resolved klass name for this method
33
+ VALUE method_name; // Resolved method name for this method
34
34
 
35
- VALUE object; // Cached ruby object
35
+ VALUE object; // Cached ruby object
36
36
 
37
37
  bool recursive;
38
- int visits; // Current visits on the stack
39
- VALUE source_file; // Source file
40
- int source_line; // Line number
38
+ int visits; // Current visits on the stack
39
+ VALUE source_file; // Source file
40
+ int source_line; // Line number
41
41
 
42
42
  prof_measurement_t* measurement; // Stores measurement data for this method
43
43
  } prof_method_t;
@@ -138,11 +138,7 @@ prof_method_t* check_method(VALUE profile, rb_trace_arg_t* trace_arg, rb_event_f
138
138
  if (klass == cProfile)
139
139
  return NULL;
140
140
 
141
- #ifdef HAVE_RB_TRACEARG_CALLEE_ID
142
141
  VALUE msym = rb_tracearg_callee_id(trace_arg);
143
- #else
144
- VALUE msym = rb_tracearg_method_id(trace_arg);
145
- #endif
146
142
 
147
143
  st_data_t key = method_key(klass, msym);
148
144
 
@@ -158,7 +154,7 @@ prof_method_t* check_method(VALUE profile, rb_trace_arg_t* trace_arg, rb_event_f
158
154
  int source_line = (event != RUBY_EVENT_C_CALL ? FIX2INT(rb_tracearg_lineno(trace_arg)) : 0);
159
155
  result = create_method(profile, key, klass, msym, source_file, source_line);
160
156
  }
161
-
157
+
162
158
  return result;
163
159
  }
164
160
 
@@ -174,11 +170,7 @@ static void prof_trace(prof_profile_t* profile, rb_trace_arg_t* trace_arg, doubl
174
170
  VALUE source_file = rb_tracearg_path(trace_arg);
175
171
  int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
176
172
 
177
- #ifdef HAVE_RB_TRACEARG_CALLEE_ID
178
173
  VALUE msym = rb_tracearg_callee_id(trace_arg);
179
- #else
180
- VALUE msym = rb_tracearg_method_id(trace_arg);
181
- #endif
182
174
 
183
175
  unsigned int klass_flags;
184
176
  VALUE klass = rb_tracearg_defined_class(trace_arg);
@@ -253,13 +245,13 @@ static void prof_event_hook(VALUE trace_point, void* data)
253
245
  {
254
246
  frame = prof_frame_push(thread_data->stack, call_tree, measurement, RTEST(profile_t->paused));
255
247
  }
256
-
248
+
257
249
  thread_data->call_tree = call_tree;
258
250
  }
259
-
251
+
260
252
  frame->source_file = rb_tracearg_path(trace_arg);
261
253
  frame->source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
262
-
254
+
263
255
  break;
264
256
  }
265
257
  case RUBY_EVENT_CALL:
@@ -282,7 +274,7 @@ static void prof_event_hook(VALUE trace_point, void* data)
282
274
  }
283
275
  else if (!frame && thread_data->call_tree)
284
276
  {
285
- // There is no current parent - likely we have returned out of the highest level method we have profiled so far.
277
+ // There is no current parent - likely we have returned out of the highest level method we have profiled so far.
286
278
  // This can happen with enumerators (see fiber_test.rb). So create a new dummy parent.
287
279
  prof_method_t* parent_method = check_parent_method(profile, thread_data);
288
280
  parent_call_tree = prof_call_tree_create(parent_method, NULL, Qnil, 0);
@@ -421,7 +413,7 @@ static void prof_profile_mark(void* data)
421
413
  rb_st_foreach(profile->exclude_methods_tbl, prof_profile_mark_methods, 0);
422
414
  }
423
415
 
424
- /* Freeing the profile creates a cascade of freeing. It frees its threads table, which frees
416
+ /* Freeing the profile creates a cascade of freeing. It frees its threads table, which frees
425
417
  each thread and its associated call treee and methods. */
426
418
  static void prof_profile_ruby_gc_free(void* data)
427
419
  {
@@ -180,7 +180,7 @@ prof_frame_t* prof_frame_pop(prof_stack_t* stack, double measurement)
180
180
  call_tree->measurement->total_time += total_time;
181
181
 
182
182
  call_tree->visits--;
183
-
183
+
184
184
  prof_frame_t* parent_frame = prof_stack_last(stack);
185
185
  if (parent_frame)
186
186
  {
@@ -21,7 +21,7 @@ You cannot create an instance of RubyProf::Thread, instead you access it from a
21
21
 
22
22
  VALUE cRpThread;
23
23
 
24
- // ====== thread_data_t ======
24
+ // ====== thread_data_t ======
25
25
  thread_data_t* thread_data_create(void)
26
26
  {
27
27
  thread_data_t* result = ALLOC(thread_data_t);
@@ -146,7 +146,7 @@ thread_data_t* prof_get_thread(VALUE self)
146
146
  }
147
147
 
148
148
  // ====== Thread Table ======
149
- // The thread table is hash keyed on ruby fiber_id that stores instances of thread_data_t.
149
+ // The thread table is hash keyed on ruby fiber_id that stores instances of thread_data_t.
150
150
 
151
151
  st_table* threads_table_create()
152
152
  {
@@ -104,7 +104,7 @@
104
104
  <ClCompile>
105
105
  <AdditionalIncludeDirectories>C:\msys64\usr\local\ruby-2.7.2vc\include\ruby-2.7.0\x64-mswin64_140;C:\msys64\usr\local\ruby-2.7.2vc\include\ruby-2.7.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
106
106
  <Optimization>Disabled</Optimization>
107
- <PreprocessorDefinitions>HAVE_RB_TRACEARG_CALLEE_ID;%(PreprocessorDefinitions)</PreprocessorDefinitions>
107
+ <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
108
108
  <WarningLevel>Level3</WarningLevel>
109
109
  </ClCompile>
110
110
  <Link>
data/lib/ruby-prof.rb CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  version = Gem::Version.new(RUBY_VERSION)
7
7
  require "#{version.segments[0..1].join('.')}/ruby_prof.so"
8
8
  rescue LoadError
9
- require "ruby_prof.so"
9
+ require_relative "../ext/ruby_prof/ruby_prof.so"
10
10
  end
11
11
 
12
12
  require 'ruby-prof/version'
@@ -113,7 +113,7 @@ module RubyProf
113
113
 
114
114
  def print_footer(thread)
115
115
  @output << <<~EOT
116
-
116
+
117
117
  * recursively called methods
118
118
 
119
119
  Columns are:
@@ -1,3 +1,3 @@
1
1
  module RubyProf
2
- VERSION = "1.4.2"
2
+ VERSION = "1.4.3"
3
3
  end
data/ruby-prof.gemspec CHANGED
@@ -56,7 +56,7 @@ EOF
56
56
  'test/*.rb']
57
57
 
58
58
  spec.test_files = Dir["test/test_*.rb"]
59
- spec.required_ruby_version = '>= 2.4.0'
59
+ spec.required_ruby_version = '>= 2.5.0'
60
60
  spec.date = Time.now.strftime('%Y-%m-%d')
61
61
  spec.homepage = 'https://github.com/ruby-prof/ruby-prof'
62
62
  spec.add_development_dependency('minitest')
data/test/gc_test.rb CHANGED
@@ -29,6 +29,8 @@ class GcTest < TestCase
29
29
  array
30
30
  end
31
31
 
32
+ GC.start
33
+
32
34
  threads.each do |thread|
33
35
  refute_nil(thread.id)
34
36
  end
@@ -42,6 +44,8 @@ class GcTest < TestCase
42
44
  array
43
45
  end
44
46
 
47
+ GC.start
48
+
45
49
  methods.each do |method|
46
50
  refute_nil(method.method_name)
47
51
  end
@@ -55,6 +59,8 @@ class GcTest < TestCase
55
59
  array
56
60
  end
57
61
 
62
+ GC.start
63
+
58
64
  method_call_infos.each do |call_trees|
59
65
  refute_empty(call_trees.call_trees)
60
66
  end
@@ -63,11 +69,13 @@ class GcTest < TestCase
63
69
  def test_hold_onto_measurements
64
70
  measurements = 5.times.reduce(Array.new) do |array, i|
65
71
  profile = run_profile
66
- measurements = profile.threads.map(&:methods).flatten.map(&:measurement)
67
- array.concat(measurements)
72
+ measurements_2 = profile.threads.map(&:methods).flatten.map(&:measurement)
73
+ array.concat(measurements_2)
68
74
  array
69
75
  end
70
76
 
77
+ GC.start
78
+
71
79
  measurements.each do |measurement|
72
80
  error = assert_raises(RuntimeError) do
73
81
  measurement.total_time
@@ -83,6 +91,8 @@ class GcTest < TestCase
83
91
  array
84
92
  end
85
93
 
94
+ GC.start
95
+
86
96
  call_trees.each do |call_tree|
87
97
  refute_nil(call_tree.source_file)
88
98
  end
data/test/marshal_test.rb CHANGED
@@ -35,7 +35,13 @@ class MarshalTest < TestCase
35
35
 
36
36
  assert_equal(method_1.recursive?, method_2.recursive?)
37
37
 
38
- assert_equal(method_1.source_file, method_2.source_file)
38
+ if method_1.source_file
39
+ assert_equal(method_1.source_file, method_2.source_file)
40
+ else
41
+ assert_nil(method_1.source_file)
42
+ assert_nil(method_2.source_file)
43
+ end
44
+
39
45
  assert_equal(method_1.line, method_2.line)
40
46
 
41
47
  verify_measurement(method_1.measurement, method_2.measurement)
@@ -73,10 +79,23 @@ class MarshalTest < TestCase
73
79
 
74
80
  def verify_call_info(call_info_1, call_info_2)
75
81
  assert_equal(call_info_1.target, call_info_2.target)
76
- assert_equal(call_info_1.parent&.target, call_info_2.parent&.target)
82
+
83
+ if call_info_1.parent&.target
84
+ assert_equal(call_info_1.parent&.target, call_info_2.parent&.target)
85
+ else
86
+ assert_nil(call_info_1.parent&.target)
87
+ assert_nil(call_info_2.parent&.target)
88
+ end
77
89
 
78
90
  assert_equal(call_info_1.depth, call_info_2.depth)
79
- assert_equal(call_info_1.source_file, call_info_2.source_file)
91
+
92
+ if call_info_1.source_file
93
+ assert_equal(call_info_1.source_file, call_info_2.source_file) #
94
+ else
95
+ assert_nil(call_info_1.source_file)
96
+ assert_nil(call_info_2.source_file)
97
+ end
98
+
80
99
  assert_equal(call_info_1.line, call_info_2.line)
81
100
 
82
101
  verify_measurement(call_info_1.measurement, call_info_2.measurement)
@@ -36,7 +36,7 @@ class MeasureMemoryTraceTest < TestCase
36
36
  assert_in_delta(800, method.children_time, 1)
37
37
 
38
38
  assert_equal(0, method.call_trees.callers.length)
39
-
39
+
40
40
  assert_equal(2, method.call_trees.callees.length)
41
41
  call_tree = method.call_trees.callees[0]
42
42
  assert_equal('Class#new', call_tree.target.full_name)
@@ -738,7 +738,7 @@ class MeasureMemoryTraceTest < TestCase
738
738
 
739
739
  assert_equal(0.0, method.call_trees.callees.length)
740
740
  end
741
- else
741
+ elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.0')
742
742
  def test_memory
743
743
  result = RubyProf.profile do
744
744
  allocator = Allocator.new
@@ -1095,6 +1095,365 @@ class MeasureMemoryTraceTest < TestCase
1095
1095
  assert_equal(0.0, call_tree.self_time)
1096
1096
  assert_equal(0.0, call_tree.children_time)
1097
1097
 
1098
+ assert_equal(0.0, method.call_trees.callees.length)
1099
+ end
1100
+ else
1101
+ def test_memory
1102
+ result = RubyProf.profile do
1103
+ allocator = Allocator.new
1104
+ allocator.run
1105
+ end
1106
+
1107
+ thread = result.threads.first
1108
+
1109
+ assert_in_delta(1680, thread.total_time, 1)
1110
+ methods = result.threads.first.methods.sort.reverse
1111
+ assert_equal(13, methods.length)
1112
+
1113
+ # Method 0
1114
+ method = methods[0]
1115
+ assert_equal('MeasureMemoryTraceTest#test_memory', method.full_name)
1116
+ assert_in_delta(1680, method.total_time, 1)
1117
+
1118
+ assert_equal(0.0, method.wait_time)
1119
+ assert_equal(80.0, method.self_time)
1120
+ assert_in_delta(1600, method.children_time, 1)
1121
+ assert_equal(0, method.call_trees.callers.length)
1122
+
1123
+ assert_equal(2, method.call_trees.callees.length)
1124
+ call_tree = method.call_trees.callees[0]
1125
+ assert_equal('Class#new', call_tree.target.full_name)
1126
+ assert_equal(40.0, call_tree.total_time)
1127
+ assert_equal(0.0, call_tree.wait_time)
1128
+ assert_equal(40.0, call_tree.self_time)
1129
+ assert_equal(0.0, call_tree.children_time)
1130
+
1131
+ call_tree = method.call_trees.callees[1]
1132
+ assert_equal('Allocator#run', call_tree.target.full_name)
1133
+ assert_equal(1560.0, call_tree.total_time)
1134
+ assert_equal(0.0, call_tree.wait_time)
1135
+ assert_equal(40.0, call_tree.self_time)
1136
+ assert_equal(1520.0, call_tree.children_time)
1137
+
1138
+ # Method 1
1139
+ method = methods[1]
1140
+ assert_equal('Allocator#run',method.full_name)
1141
+ assert_equal(1560.0, method.total_time)
1142
+ assert_equal(0.0, method.wait_time)
1143
+ assert_equal(40.0, method.self_time)
1144
+ assert_equal(1520.0, method.children_time)
1145
+
1146
+ assert_equal(1, method.call_trees.callers.length)
1147
+ call_tree = method.call_trees.callers[0]
1148
+ assert_equal('MeasureMemoryTraceTest#test_memory', call_tree.parent.target.full_name)
1149
+ assert_equal(1560.0, call_tree.total_time)
1150
+ assert_equal(0.0, call_tree.wait_time)
1151
+ assert_equal(40.0, call_tree.self_time)
1152
+ assert_equal(1520.0, call_tree.children_time)
1153
+
1154
+ assert_equal(1, method.call_trees.callees.length)
1155
+ call_tree = method.call_trees.callees[0]
1156
+ assert_equal('Allocator#internal_run', call_tree.target.full_name)
1157
+ assert_equal(1520.0, call_tree.total_time)
1158
+ assert_equal(0.0, call_tree.wait_time)
1159
+ assert_equal(120.0, call_tree.self_time)
1160
+ assert_equal(1400.0, call_tree.children_time)
1161
+
1162
+ # Method 2
1163
+ method = methods[2]
1164
+ assert_equal('Allocator#internal_run', method.full_name)
1165
+ assert_equal(1520.0, method.total_time)
1166
+ assert_equal(0.0, method.wait_time)
1167
+ assert_equal(120.0, method.self_time)
1168
+ assert_equal(1400.0, method.children_time)
1169
+
1170
+ assert_equal(1, method.call_trees.callers.length)
1171
+ call_tree = method.call_trees.callers[0]
1172
+ assert_equal('Allocator#run', call_tree.parent.target.full_name)
1173
+ assert_equal(1520.0, call_tree.total_time)
1174
+ assert_equal(0.0, call_tree.wait_time)
1175
+ assert_equal(120.0, call_tree.self_time)
1176
+ assert_equal(1400.0, call_tree.children_time)
1177
+
1178
+ assert_equal(3, method.call_trees.callees.length)
1179
+ call_tree = method.call_trees.callees[0]
1180
+ assert_equal('Allocator#make_arrays', call_tree.target.full_name)
1181
+ assert_equal(400.0, call_tree.total_time)
1182
+ assert_equal(0.0, call_tree.wait_time)
1183
+ assert_equal(0.0, call_tree.self_time)
1184
+ assert_equal(400.0, call_tree.children_time)
1185
+
1186
+ call_tree = method.call_trees.callees[1]
1187
+ assert_equal('Allocator#make_hashes', call_tree.target.full_name)
1188
+ assert_equal(840.0, call_tree.total_time)
1189
+ assert_equal(0.0, call_tree.wait_time)
1190
+ assert_equal(0.0, call_tree.self_time)
1191
+ assert_equal(840.0, call_tree.children_time)
1192
+
1193
+ call_tree = method.call_trees.callees[2]
1194
+ assert_equal('Allocator#make_strings', call_tree.target.full_name)
1195
+ assert_equal(160.0, call_tree.total_time)
1196
+ assert_equal(0.0, call_tree.wait_time)
1197
+ assert_equal(40, call_tree.self_time)
1198
+ assert_equal(120.0, call_tree.children_time)
1199
+
1200
+ # Method 3
1201
+ method = methods[3]
1202
+ assert_equal('Class#new', method.full_name)
1203
+ assert_equal(1360.0, method.total_time)
1204
+ assert_equal(0.0, method.wait_time)
1205
+ assert_equal(1320.0, method.self_time)
1206
+ assert_equal(40.0, method.children_time)
1207
+
1208
+ assert_equal(4, method.call_trees.callers.length)
1209
+ call_tree = method.call_trees.callers[0]
1210
+ assert_equal('MeasureMemoryTraceTest#test_memory', call_tree.parent.target.full_name)
1211
+ assert_equal(40.0, call_tree.total_time)
1212
+ assert_equal(0.0, call_tree.wait_time)
1213
+ assert_equal(40.0, call_tree.self_time)
1214
+ assert_equal(0.0, call_tree.children_time)
1215
+
1216
+ call_tree = method.call_trees.callers[1]
1217
+ assert_equal('Integer#times', call_tree.parent.target.full_name)
1218
+ assert_equal(400.0, call_tree.total_time)
1219
+ assert_equal(0.0, call_tree.wait_time)
1220
+ assert_equal(400.0, call_tree.self_time)
1221
+ assert_equal(0.0, call_tree.children_time)
1222
+
1223
+ call_tree = method.call_trees.callers[2]
1224
+ assert_equal('Allocator#make_hashes', call_tree.parent.target.full_name)
1225
+ assert_equal(840.0, call_tree.total_time)
1226
+ assert_equal(0.0, call_tree.wait_time)
1227
+ assert_equal(840.0, call_tree.self_time)
1228
+ assert_equal(0.0, call_tree.children_time)
1229
+
1230
+ call_tree = method.call_trees.callers[3]
1231
+ assert_equal('Allocator#make_strings', call_tree.parent.target.full_name)
1232
+ assert_equal(80.0, call_tree.total_time)
1233
+ assert_equal(0.0, call_tree.wait_time)
1234
+ assert_equal(40.0, call_tree.self_time)
1235
+ assert_equal(40.0, call_tree.children_time)
1236
+
1237
+ assert_equal(4, method.call_trees.callees.length)
1238
+ call_tree = method.call_trees.callees[0]
1239
+ assert_equal('BasicObject#initialize', call_tree.target.full_name)
1240
+ assert_equal(0.0, call_tree.total_time)
1241
+ assert_equal(0.0, call_tree.wait_time)
1242
+ assert_equal(0.0, call_tree.self_time)
1243
+ assert_equal(0.0, call_tree.children_time)
1244
+
1245
+ call_tree = method.call_trees.callees[1]
1246
+ assert_equal('Array#initialize', call_tree.target.full_name)
1247
+ assert_equal(0.0, call_tree.total_time)
1248
+ assert_equal(0.0, call_tree.wait_time)
1249
+ assert_equal(0.0, call_tree.self_time)
1250
+ assert_equal(0.0, call_tree.children_time)
1251
+
1252
+ call_tree = method.call_trees.callees[2]
1253
+ assert_equal('Hash#initialize', call_tree.target.full_name)
1254
+ assert_equal(0.0, call_tree.total_time)
1255
+ assert_equal(0.0, call_tree.wait_time)
1256
+ assert_equal(0.0, call_tree.self_time)
1257
+ assert_equal(0.0, call_tree.children_time)
1258
+
1259
+ call_tree = method.call_trees.callees[3]
1260
+ assert_equal('String#initialize', call_tree.target.full_name)
1261
+ assert_equal(40.0, call_tree.total_time)
1262
+ assert_equal(0.0, call_tree.wait_time)
1263
+ assert_equal(40.0, call_tree.self_time)
1264
+ assert_equal(0.0, call_tree.children_time)
1265
+
1266
+ # Method 4
1267
+ method = methods[4]
1268
+ assert_equal('Allocator#make_hashes', method.full_name)
1269
+ assert_equal(840.0, method.total_time)
1270
+ assert_equal(0.0, method.wait_time)
1271
+ assert_equal(0.0, method.self_time)
1272
+ assert_equal(840.0, method.children_time)
1273
+
1274
+ assert_equal(1, method.call_trees.callers.length)
1275
+ call_tree = method.call_trees.callers[0]
1276
+ assert_equal('Allocator#internal_run', call_tree.parent.target.full_name)
1277
+ assert_equal(840.0, call_tree.total_time)
1278
+ assert_equal(0.0, call_tree.wait_time)
1279
+ assert_equal(0.0, call_tree.self_time)
1280
+ assert_equal(840.0, call_tree.children_time)
1281
+
1282
+ assert_equal(1, method.call_trees.callees.length)
1283
+ call_tree = method.call_trees.callees[0]
1284
+ assert_equal('Class#new', call_tree.target.full_name)
1285
+ assert_equal(840.0, call_tree.total_time)
1286
+ assert_equal(0.0, call_tree.wait_time)
1287
+ assert_equal(840.0, call_tree.self_time)
1288
+ assert_equal(0.0, call_tree.children_time)
1289
+
1290
+ # Method 5
1291
+ method = methods[5]
1292
+ assert_equal('Allocator#make_arrays', method.full_name)
1293
+ assert_equal(400.0, method.total_time)
1294
+ assert_equal(0.0, method.wait_time)
1295
+ assert_equal(0.0, method.self_time)
1296
+ assert_equal(400.0, method.children_time)
1297
+
1298
+ assert_equal(1, method.call_trees.callers.length)
1299
+ call_tree = method.call_trees.callers[0]
1300
+ assert_equal('Allocator#internal_run', call_tree.parent.target.full_name)
1301
+ assert_equal(400.0, call_tree.total_time)
1302
+ assert_equal(0.0, call_tree.wait_time)
1303
+ assert_equal(0.0, call_tree.self_time)
1304
+ assert_equal(400.0, call_tree.children_time)
1305
+
1306
+ assert_equal(1, method.call_trees.callees.length)
1307
+ call_tree = method.call_trees.callees[0]
1308
+ assert_equal('Integer#times', call_tree.target.full_name)
1309
+ assert_equal(400.0, call_tree.total_time)
1310
+ assert_equal(0.0, call_tree.wait_time)
1311
+ assert_equal(0.0, call_tree.self_time)
1312
+ assert_equal(400.0, call_tree.children_time)
1313
+
1314
+ # Method 6
1315
+ method = methods[6]
1316
+ assert_equal('Integer#times', method.full_name)
1317
+ assert_equal(400.0, method.total_time)
1318
+ assert_equal(0.0, method.wait_time)
1319
+ assert_equal(0.0, method.self_time)
1320
+ assert_equal(400.0, method.children_time)
1321
+
1322
+ assert_equal(1, method.call_trees.callers.length)
1323
+ call_tree = method.call_trees.callers[0]
1324
+ assert_equal('Allocator#make_arrays', call_tree.parent.target.full_name)
1325
+ assert_equal(400.0, call_tree.total_time)
1326
+ assert_equal(0.0, call_tree.wait_time)
1327
+ assert_equal(0.0, call_tree.self_time)
1328
+ assert_equal(400.0, call_tree.children_time)
1329
+
1330
+ assert_equal(1, method.call_trees.callees.length)
1331
+ call_tree = method.call_trees.callees[0]
1332
+ assert_equal('Class#new', call_tree.target.full_name)
1333
+ assert_equal(400.0, call_tree.total_time)
1334
+ assert_equal(0.0, call_tree.wait_time)
1335
+ assert_equal(400.0, call_tree.self_time)
1336
+ assert_equal(0.0, call_tree.children_time)
1337
+
1338
+ # Method 7
1339
+ method = methods[7]
1340
+ assert_equal('Allocator#make_strings', method.full_name)
1341
+ assert_equal(160.0, method.total_time)
1342
+ assert_equal(0.0, method.wait_time)
1343
+ assert_equal(40.0, method.self_time)
1344
+ assert_equal(120.0, method.children_time)
1345
+
1346
+ assert_equal(1, method.call_trees.callers.length)
1347
+ call_tree = method.call_trees.callers[0]
1348
+ assert_equal('Allocator#internal_run', call_tree.parent.target.full_name)
1349
+ assert_equal(160.0, call_tree.total_time)
1350
+ assert_equal(0.0, call_tree.wait_time)
1351
+ assert_equal(40.0, call_tree.self_time)
1352
+ assert_equal(120.0, call_tree.children_time)
1353
+
1354
+ assert_equal(2, method.call_trees.callees.length)
1355
+ call_tree = method.call_trees.callees[0]
1356
+ assert_equal('String#*', call_tree.target.full_name)
1357
+ assert_equal(40.0, call_tree.total_time)
1358
+ assert_equal(0.0, call_tree.wait_time)
1359
+ assert_equal(40.0, call_tree.self_time)
1360
+ assert_equal(0.0, call_tree.children_time)
1361
+
1362
+ call_tree = method.call_trees.callees[1]
1363
+ assert_equal('Class#new', call_tree.target.full_name)
1364
+ assert_equal(80.0, call_tree.total_time)
1365
+ assert_equal(0.0, call_tree.wait_time)
1366
+ assert_equal(40.0, call_tree.self_time)
1367
+ assert_equal(40.0, call_tree.children_time)
1368
+
1369
+ # Method 8
1370
+ method = methods[8]
1371
+ assert_equal('String#*', method.full_name)
1372
+ assert_equal(40.0, method.total_time)
1373
+ assert_equal(0.0, method.wait_time)
1374
+ assert_equal(40.0, method.self_time)
1375
+ assert_equal(0.0, method.children_time)
1376
+
1377
+ assert_equal(1, method.call_trees.callers.length)
1378
+ call_tree = method.call_trees.callers[0]
1379
+ assert_equal('Allocator#make_strings', call_tree.parent.target.full_name)
1380
+ assert_equal(40.0, call_tree.total_time)
1381
+ assert_equal(0.0, call_tree.wait_time)
1382
+ assert_equal(40.0, call_tree.self_time)
1383
+ assert_equal(0.0, call_tree.children_time)
1384
+
1385
+ assert_equal(0.0, method.call_trees.callees.length)
1386
+
1387
+ # Method 9
1388
+ method = methods[9]
1389
+ assert_equal('String#initialize', method.full_name)
1390
+ assert_equal(40.0, method.total_time)
1391
+ assert_equal(0.0, method.wait_time)
1392
+ assert_equal(40.0, method.self_time)
1393
+ assert_equal(0.0, method.children_time)
1394
+
1395
+ assert_equal(1, method.call_trees.callers.length)
1396
+ call_tree = method.call_trees.callers[0]
1397
+ assert_equal('Class#new', call_tree.parent.target.full_name)
1398
+ assert_equal(40.0, call_tree.total_time)
1399
+ assert_equal(0.0, call_tree.wait_time)
1400
+ assert_equal(40.0, call_tree.self_time)
1401
+ assert_equal(0.0, call_tree.children_time)
1402
+
1403
+ assert_equal(0.0, method.call_trees.callees.length)
1404
+
1405
+ # Method 10
1406
+ method = methods[10]
1407
+ assert_equal('BasicObject#initialize', method.full_name)
1408
+ assert_equal(0.0, method.total_time)
1409
+ assert_equal(0.0, method.wait_time)
1410
+ assert_equal(0.0, method.self_time)
1411
+ assert_equal(0.0, method.children_time)
1412
+
1413
+ assert_equal(1, method.call_trees.callers.length)
1414
+ call_tree = method.call_trees.callers[0]
1415
+ assert_equal('Class#new', call_tree.parent.target.full_name)
1416
+ assert_equal(0.0, call_tree.total_time)
1417
+ assert_equal(0.0, call_tree.wait_time)
1418
+ assert_equal(0.0, call_tree.self_time)
1419
+ assert_equal(0.0, call_tree.children_time)
1420
+
1421
+ assert_equal(0.0, method.call_trees.callees.length)
1422
+
1423
+ # Method 11
1424
+ method = methods[11]
1425
+ assert_equal('Hash#initialize', method.full_name)
1426
+ assert_equal(0.0, method.total_time)
1427
+ assert_equal(0.0, method.wait_time)
1428
+ assert_equal(0.0, method.self_time)
1429
+ assert_equal(0.0, method.children_time)
1430
+
1431
+ assert_equal(1, method.call_trees.callers.length)
1432
+ call_tree = method.call_trees.callers[0]
1433
+ assert_equal('Class#new', call_tree.parent.target.full_name)
1434
+ assert_equal(0.0, call_tree.total_time)
1435
+ assert_equal(0.0, call_tree.wait_time)
1436
+ assert_equal(0.0, call_tree.self_time)
1437
+ assert_equal(0.0, call_tree.children_time)
1438
+
1439
+ assert_equal(0.0, method.call_trees.callees.length)
1440
+
1441
+ # Method 12
1442
+ method = methods[12]
1443
+ assert_equal('Array#initialize', method.full_name)
1444
+ assert_equal(0.0, method.total_time)
1445
+ assert_equal(0.0, method.wait_time)
1446
+ assert_equal(0.0, method.self_time)
1447
+ assert_equal(0.0, method.children_time)
1448
+
1449
+ assert_equal(1, method.call_trees.callers.length)
1450
+ call_tree = method.call_trees.callers[0]
1451
+ assert_equal('Class#new', call_tree.parent.target.full_name)
1452
+ assert_equal(0.0, call_tree.total_time)
1453
+ assert_equal(0.0, call_tree.wait_time)
1454
+ assert_equal(0.0, call_tree.self_time)
1455
+ assert_equal(0.0, call_tree.children_time)
1456
+
1098
1457
  assert_equal(0.0, method.call_trees.callees.length)
1099
1458
  end
1100
1459
  end
@@ -37,7 +37,7 @@ class PrinterFlatTest < TestCase
37
37
  array = array.map(&:to_f) # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
38
38
  assert_equal(array, array.sort.reverse)
39
39
  end
40
-
40
+
41
41
  def test_flat_string
42
42
  output = helper_test_flat_string(RubyProf::FlatPrinter)
43
43
  assert_match(/prime.rb/, output)
@@ -37,10 +37,10 @@ class PrintersTest < TestCase
37
37
  end
38
38
 
39
39
  def test_print_to_files
40
- output_dir = 'examples2'
40
+ output_dir = 'tmp/examples2'
41
41
 
42
42
  if ENV['SAVE_NEW_PRINTER_EXAMPLES']
43
- output_dir = 'examples'
43
+ output_dir = 'tmp/examples'
44
44
  end
45
45
  FileUtils.mkdir_p output_dir
46
46
 
@@ -22,23 +22,23 @@ class StartStopTest < TestCase
22
22
  sleep(2)
23
23
  @result = RubyProf.stop
24
24
  end
25
-
25
+
26
26
  def test_extra_stop_should_raise
27
27
  RubyProf.start
28
28
  assert_raises(RuntimeError) do
29
29
  RubyProf.start
30
30
  end
31
-
31
+
32
32
  assert_raises(RuntimeError) do
33
33
  RubyProf.profile {}
34
34
  end
35
-
35
+
36
36
  RubyProf.stop # ok
37
37
  assert_raises(RuntimeError) do
38
38
  RubyProf.stop
39
39
  end
40
40
  end
41
-
41
+
42
42
  def test_different_methods
43
43
  method1
44
44
 
data/test/temp.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'redis'
2
+
3
+ path = File.expand_path(File.join(__dir__, '..', 'lib'))
4
+ $LOAD_PATH << path
5
+ require 'ruby-prof'
6
+
7
+ Widget = Struct.new(:key) do
8
+ def set!
9
+ Redis.current.set(key, 1, ex: 10)
10
+ end
11
+ end
12
+
13
+ result = RubyProf.profile do
14
+ (1..20).each { |i| Widget.new(i).set! }
15
+ end
16
+
17
+ printer = RubyProf::CallStackPrinter.new(result)
18
+ File.open("framez.html", 'w:ASCII-8BIT') do |file|
19
+ printer.print(file, {})
20
+ end
data/test/test_helper.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'bundler/setup'
4
+ require 'minitest/autorun'
5
+
3
6
  # Disable minitest parallel tests. The problem is the thread switching will change test results
4
7
  # (self vs wait time)
5
- ENV["N"] = "0" # Older versions of minitest
6
- ENV["MT_CPU"] = "0" # Newer versions minitest
8
+ if Gem::Version.new(Minitest::VERSION) > Gem::Version.new('5.11.3')
9
+ ENV["MT_CPU"] = "0" # Newer versions minitest
10
+ else
11
+ ENV["N"] = "0" # Older versions of minitest
12
+ end
7
13
 
8
- require 'bundler/setup'
9
- require 'minitest/autorun'
10
14
  require 'ruby-prof'
11
15
 
12
16
  class TestCase < Minitest::Test
13
- end
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-04 00:00:00.000000000 Z
11
+ date: 2021-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -167,6 +167,7 @@ files:
167
167
  - test/singleton_test.rb
168
168
  - test/stack_printer_test.rb
169
169
  - test/start_stop_test.rb
170
+ - test/temp.rb
170
171
  - test/test_helper.rb
171
172
  - test/thread_test.rb
172
173
  - test/unique_call_path_test.rb
@@ -178,7 +179,7 @@ metadata:
178
179
  bug_tracker_uri: https://github.com/ruby-prof/ruby-prof/issues
179
180
  changelog_uri: https://github.com/ruby-prof/ruby-prof/blob/master/CHANGES
180
181
  documentation_uri: https://ruby-prof.github.io/
181
- source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/v1.4.2
182
+ source_code_uri: https://github.com/ruby-prof/ruby-prof/tree/v1.4.3
182
183
  post_install_message:
183
184
  rdoc_options: []
184
185
  require_paths:
@@ -187,7 +188,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
187
188
  requirements:
188
189
  - - ">="
189
190
  - !ruby/object:Gem::Version
190
- version: 2.4.0
191
+ version: 2.5.0
191
192
  required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  requirements:
193
194
  - - ">="