ruby-prof 1.6.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +7 -0
  3. data/ext/ruby_prof/rp_allocation.c +342 -342
  4. data/ext/ruby_prof/rp_call_tree.c +1 -1
  5. data/ext/ruby_prof/rp_call_tree.h +1 -1
  6. data/ext/ruby_prof/rp_call_trees.c +2 -2
  7. data/ext/ruby_prof/rp_call_trees.h +2 -2
  8. data/ext/ruby_prof/rp_measure_allocations.c +1 -1
  9. data/ext/ruby_prof/rp_measure_memory.c +46 -46
  10. data/ext/ruby_prof/rp_measure_process_time.c +1 -1
  11. data/ext/ruby_prof/rp_measure_wall_time.c +1 -1
  12. data/ext/ruby_prof/rp_measurement.c +364 -364
  13. data/ext/ruby_prof/rp_method.c +24 -12
  14. data/ext/ruby_prof/rp_method.h +5 -2
  15. data/ext/ruby_prof/rp_profile.c +2 -2
  16. data/ext/ruby_prof/rp_profile.h +36 -36
  17. data/ext/ruby_prof/rp_stack.c +1 -1
  18. data/ext/ruby_prof/rp_thread.c +1 -1
  19. data/ext/ruby_prof/ruby_prof.c +1 -1
  20. data/ext/ruby_prof/ruby_prof.h +34 -34
  21. data/ext/ruby_prof/vc/ruby_prof.vcxproj +5 -7
  22. data/lib/ruby-prof/compatibility.rb +10 -10
  23. data/lib/ruby-prof/exclude_common_methods.rb +9 -3
  24. data/lib/ruby-prof/method_info.rb +87 -85
  25. data/lib/ruby-prof/version.rb +1 -1
  26. data/ruby-prof.gemspec +1 -1
  27. data/test/crash2.rb +144 -0
  28. data/test/enumerable_test.rb +5 -5
  29. data/test/exclude_methods_test.rb +197 -86
  30. data/test/line_number_test.rb +254 -99
  31. data/test/measure_allocations_test.rb +422 -1
  32. data/test/measure_memory_test.rb +433 -1
  33. data/test/measure_process_time_test.rb +882 -15
  34. data/test/measure_wall_time_test.rb +195 -47
  35. data/test/method_info_test.rb +1 -1
  36. data/test/recursive_test.rb +198 -1
  37. data/test/thread_test.rb +0 -4
  38. metadata +6 -5
@@ -4,6 +4,17 @@
4
4
  #include "rp_allocation.h"
5
5
  #include "rp_call_trees.h"
6
6
  #include "rp_method.h"
7
+ #include "rp_profile.h"
8
+
9
+ #include <ruby/version.h>
10
+
11
+ // Needed for Ruby 3.0.* and 3.1.*
12
+ #if RUBY_API_VERSION_MAJOR == 3 && RUBY_API_VERSION_MINOR < 2
13
+ VALUE rb_class_attached_object(VALUE klass)
14
+ {
15
+ return rb_iv_get(klass, "__attached__");
16
+ }
17
+ #endif
7
18
 
8
19
  VALUE cRpMethodInfo;
9
20
 
@@ -20,7 +31,7 @@ VALUE resolve_klass(VALUE klass, unsigned int* klass_flags)
20
31
  {
21
32
  /* We have come across a singleton object. First
22
33
  figure out what it is attached to.*/
23
- VALUE attached = rb_iv_get(klass, "__attached__");
34
+ VALUE attached = rb_class_attached_object(klass);
24
35
 
25
36
  switch (BUILTIN_TYPE(attached))
26
37
  {
@@ -125,7 +136,7 @@ prof_method_t* prof_get_method(VALUE self)
125
136
  return result;
126
137
  }
127
138
 
128
- prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE source_file, int source_line)
139
+ prof_method_t* prof_method_create(struct prof_profile_t* profile, VALUE klass, VALUE msym, VALUE source_file, int source_line)
129
140
  {
130
141
  prof_method_t* result = ALLOC(prof_method_t);
131
142
  result->profile = profile;
@@ -204,14 +215,16 @@ void prof_method_mark(void* data)
204
215
 
205
216
  prof_method_t* method = (prof_method_t*)data;
206
217
 
207
- if (method->profile != Qnil)
208
- rb_gc_mark_movable(method->profile);
209
-
210
218
  if (method->object != Qnil)
211
- rb_gc_mark_movable(method->object);
219
+ rb_gc_mark_movable(method->object);
220
+
221
+ // Mark the profile to keep it alive. Can't call prof_profile_mark because that would
222
+ // cause recursion
223
+ if (method->profile && method->profile->object != Qnil)
224
+ rb_gc_mark(method->profile->object);
212
225
 
213
- rb_gc_mark_movable(method->klass_name);
214
- rb_gc_mark_movable(method->method_name);
226
+ rb_gc_mark(method->klass_name);
227
+ rb_gc_mark(method->method_name);
215
228
  rb_gc_mark(method->source_file);
216
229
 
217
230
  if (method->klass != Qnil)
@@ -225,14 +238,13 @@ void prof_method_compact(void* data)
225
238
  {
226
239
  prof_method_t* method = (prof_method_t*)data;
227
240
  method->object = rb_gc_location(method->object);
228
- method->profile = rb_gc_location(method->profile);
229
241
  method->klass_name = rb_gc_location(method->klass_name);
230
242
  method->method_name = rb_gc_location(method->method_name);
231
243
  }
232
244
 
233
245
  static VALUE prof_method_allocate(VALUE klass)
234
246
  {
235
- prof_method_t* method_data = prof_method_create(Qnil, Qnil, Qnil, Qnil, 0);
247
+ prof_method_t* method_data = prof_method_create(NULL, Qnil, Qnil, Qnil, 0);
236
248
  method_data->object = prof_method_wrap(method_data);
237
249
  return method_data->object;
238
250
  }
@@ -260,7 +272,7 @@ VALUE prof_method_wrap(prof_method_t* method)
260
272
  return method->object;
261
273
  }
262
274
 
263
- st_table* method_table_create()
275
+ st_table* method_table_create(void)
264
276
  {
265
277
  return rb_st_init_numtable();
266
278
  }
@@ -516,7 +528,7 @@ static VALUE prof_method_load(VALUE self, VALUE data)
516
528
  return data;
517
529
  }
518
530
 
519
- void rp_init_method_info()
531
+ void rp_init_method_info(void)
520
532
  {
521
533
  /* MethodInfo */
522
534
  cRpMethodInfo = rb_define_class_under(mProf, "MethodInfo", rb_cObject);
@@ -18,11 +18,14 @@ enum {
18
18
  kOtherSingleton = 0x10 // Singleton of unknown object
19
19
  };
20
20
 
21
+ // Don't want to include ruby_prof.h to avoid a circular reference
22
+ struct prof_profile_t;
23
+
21
24
  // Profiling information for each method.
22
25
  // Excluded methods have no call_trees, source_klass, or source_file.
23
26
  typedef struct prof_method_t
24
27
  {
25
- VALUE profile; // Profile this method is associated with - needed for mark phase
28
+ struct prof_profile_t* profile; // Profile this method is associated with - needed for mark phase
26
29
  struct prof_call_trees_t* call_trees; // Call infos that call this method
27
30
  st_table* allocations_table; // Tracks object allocations
28
31
 
@@ -51,7 +54,7 @@ prof_method_t* method_table_lookup(st_table* table, st_data_t key);
51
54
  size_t method_table_insert(st_table* table, st_data_t key, prof_method_t* val);
52
55
  void method_table_free(st_table* table);
53
56
  void prof_method_table_merge(st_table* self, st_table* other);
54
- prof_method_t* prof_method_create(VALUE profile, VALUE klass, VALUE msym, VALUE source_file, int source_line);
57
+ prof_method_t* prof_method_create(struct prof_profile_t* profile, VALUE klass, VALUE msym, VALUE source_file, int source_line);
55
58
  prof_method_t* prof_get_method(VALUE self);
56
59
 
57
60
  VALUE prof_method_wrap(prof_method_t* result);
@@ -105,7 +105,7 @@ static int excludes_method(st_data_t key, prof_profile_t* profile)
105
105
 
106
106
  static prof_method_t* create_method(prof_profile_t* profile, st_data_t key, VALUE klass, VALUE msym, VALUE source_file, int source_line)
107
107
  {
108
- prof_method_t* result = prof_method_create(profile->object, klass, msym, source_file, source_line);
108
+ prof_method_t* result = prof_method_create(profile, klass, msym, source_file, source_line);
109
109
  method_table_insert(profile->last_thread_data->method_table, result->key, result);
110
110
 
111
111
  return result;
@@ -863,7 +863,7 @@ static VALUE prof_exclude_method(VALUE self, VALUE klass, VALUE msym)
863
863
 
864
864
  if (!method)
865
865
  {
866
- method = prof_method_create(self, klass, msym, Qnil, 0);
866
+ method = prof_method_create(profile, klass, msym, Qnil, 0);
867
867
  method_table_insert(profile->exclude_methods_tbl, method->key, method);
868
868
  }
869
869
 
@@ -1,36 +1,36 @@
1
- /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
- Please see the LICENSE file for copyright and distribution information */
3
-
4
- #ifndef __RP_PROFILE_H__
5
- #define __RP_PROFILE_H__
6
-
7
- #include "ruby_prof.h"
8
- #include "rp_measurement.h"
9
- #include "rp_thread.h"
10
-
11
- extern VALUE cProfile;
12
-
13
- typedef struct prof_profile_t
14
- {
15
- VALUE object;
16
- VALUE running;
17
- VALUE paused;
18
-
19
- prof_measurer_t* measurer;
20
-
21
- VALUE tracepoints;
22
-
23
- st_table* threads_tbl;
24
- st_table* exclude_threads_tbl;
25
- st_table* include_threads_tbl;
26
- st_table* exclude_methods_tbl;
27
- thread_data_t* last_thread_data;
28
- double measurement_at_pause_resume;
29
- bool allow_exceptions;
30
- } prof_profile_t;
31
-
32
- void rp_init_profile(void);
33
- prof_profile_t* prof_get_profile(VALUE self);
34
-
35
-
36
- #endif //__RP_PROFILE_H__
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #ifndef __RP_PROFILE_H__
5
+ #define __RP_PROFILE_H__
6
+
7
+ #include "ruby_prof.h"
8
+ #include "rp_measurement.h"
9
+ #include "rp_thread.h"
10
+
11
+ extern VALUE cProfile;
12
+
13
+ typedef struct prof_profile_t
14
+ {
15
+ VALUE object;
16
+ VALUE running;
17
+ VALUE paused;
18
+
19
+ prof_measurer_t* measurer;
20
+
21
+ VALUE tracepoints;
22
+
23
+ st_table* threads_tbl;
24
+ st_table* exclude_threads_tbl;
25
+ st_table* include_threads_tbl;
26
+ st_table* exclude_methods_tbl;
27
+ thread_data_t* last_thread_data;
28
+ double measurement_at_pause_resume;
29
+ bool allow_exceptions;
30
+ } prof_profile_t;
31
+
32
+ void rp_init_profile(void);
33
+ prof_profile_t* prof_get_profile(VALUE self);
34
+
35
+
36
+ #endif //__RP_PROFILE_H__
@@ -6,7 +6,7 @@
6
6
  #define INITIAL_STACK_SIZE 16
7
7
 
8
8
  // Creates a stack of prof_frame_t to keep track of timings for active methods.
9
- prof_stack_t* prof_stack_create()
9
+ prof_stack_t* prof_stack_create(void)
10
10
  {
11
11
  prof_stack_t* stack = ALLOC(prof_stack_t);
12
12
  stack->start = ZALLOC_N(prof_frame_t, INITIAL_STACK_SIZE);
@@ -172,7 +172,7 @@ thread_data_t* prof_get_thread(VALUE self)
172
172
  // ====== Thread Table ======
173
173
  // The thread table is hash keyed on ruby fiber_id that stores instances of thread_data_t.
174
174
 
175
- st_table* threads_table_create()
175
+ st_table* threads_table_create(void)
176
176
  {
177
177
  return rb_st_init_numtable();
178
178
  }
@@ -36,7 +36,7 @@
36
36
 
37
37
  VALUE mProf;
38
38
 
39
- void Init_ruby_prof()
39
+ void Init_ruby_prof(void)
40
40
  {
41
41
  mProf = rb_define_module("RubyProf");
42
42
 
@@ -1,34 +1,34 @@
1
- /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
- Please see the LICENSE file for copyright and distribution information */
3
-
4
- #ifndef __RUBY_PROF_H__
5
- #define __RUBY_PROF_H__
6
-
7
- #include <ruby.h>
8
- #include <ruby/debug.h>
9
- #include <stdio.h>
10
- #include <stdbool.h>
11
-
12
- #ifndef rb_st_lookup
13
- #define rb_st_foreach st_foreach
14
- #define rb_st_free_table st_free_table
15
- #define rb_st_init_numtable st_init_numtable
16
- #define rb_st_insert st_insert
17
- #define rb_st_lookup st_lookup
18
- #endif
19
-
20
-
21
- extern VALUE mProf;
22
-
23
- // This method is not exposed in Ruby header files - at least not as of Ruby 2.6.3 :(
24
- extern size_t rb_obj_memsize_of(VALUE);
25
-
26
- typedef enum
27
- {
28
- OWNER_UNKNOWN = 0,
29
- OWNER_RUBY = 1,
30
- OWNER_C = 2
31
- } prof_owner_t;
32
-
33
-
34
- #endif //__RUBY_PROF_H__
1
+ /* Copyright (C) 2005-2019 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
+ Please see the LICENSE file for copyright and distribution information */
3
+
4
+ #ifndef __RUBY_PROF_H__
5
+ #define __RUBY_PROF_H__
6
+
7
+ #include <ruby.h>
8
+ #include <ruby/debug.h>
9
+ #include <stdio.h>
10
+ #include <stdbool.h>
11
+
12
+ #ifndef rb_st_lookup
13
+ #define rb_st_foreach st_foreach
14
+ #define rb_st_free_table st_free_table
15
+ #define rb_st_init_numtable st_init_numtable
16
+ #define rb_st_insert st_insert
17
+ #define rb_st_lookup st_lookup
18
+ #endif
19
+
20
+
21
+ extern VALUE mProf;
22
+
23
+ // This method is not exposed in Ruby header files - at least not as of Ruby 2.6.3 :(
24
+ extern size_t rb_obj_memsize_of(VALUE);
25
+
26
+ typedef enum
27
+ {
28
+ OWNER_UNKNOWN = 0,
29
+ OWNER_RUBY = 1,
30
+ OWNER_C = 2
31
+ } prof_owner_t;
32
+
33
+
34
+ #endif //__RUBY_PROF_H__
@@ -66,7 +66,7 @@
66
66
  </PropertyGroup>
67
67
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
68
68
  <TargetExt>.so</TargetExt>
69
- <OutDir>$(SolutionDir)\..</OutDir>
69
+ <OutDir>$(SolutionDir)\..\</OutDir>
70
70
  </PropertyGroup>
71
71
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
72
72
  <ClCompile>
@@ -104,20 +104,18 @@
104
104
  </ItemDefinitionGroup>
105
105
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
106
106
  <ClCompile>
107
- <AdditionalIncludeDirectories>C:\msys64\usr\local\ruby-3.2.1-vc\include\ruby-3.2.0\x64-mswin64_140;C:\msys64\usr\local\ruby-3.2.1-vc\include\ruby-3.2.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
107
+ <AdditionalIncludeDirectories>C:\msys64\usr\local\ruby-3.3.0-vc\include\ruby-3.3.0\x64-mswin64_140;C:\msys64\usr\local\ruby-3.3.0-vc\include\ruby-3.3.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
108
108
  <Optimization>Disabled</Optimization>
109
109
  <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
110
110
  <WarningLevel>Level3</WarningLevel>
111
111
  </ClCompile>
112
112
  <Link>
113
- <AdditionalLibraryDirectories>C:\msys64\usr\local\ruby-3.2.1-vc\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
114
- <AdditionalDependencies>x64-vcruntime140-ruby320.lib;%(AdditionalDependencies)</AdditionalDependencies>
113
+ <AdditionalLibraryDirectories>C:\msys64\usr\local\ruby-3.3.0-vc\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
114
+ <AdditionalDependencies>x64-vcruntime140-ruby330.lib;%(AdditionalDependencies)</AdditionalDependencies>
115
115
  <ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
116
116
  <SubSystem>Console</SubSystem>
117
117
  </Link>
118
- <ProjectReference>
119
- <LinkLibraryDependencies>false</LinkLibraryDependencies>
120
- </ProjectReference>
118
+ <ProjectReference />
121
119
  </ItemDefinitionGroup>
122
120
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
123
121
  <ClCompile>
@@ -99,15 +99,15 @@ module RubyProf
99
99
 
100
100
  class << self
101
101
  extend Gem::Deprecate
102
- deprecate :measure_mode, "Profile#measure_mode", 2023, 6
103
- deprecate :measure_mode=, "Profile#measure_mode=", 2023, 6
104
- deprecate :exclude_threads, "Profile#exclude_threads", 2023, 6
105
- deprecate :exclude_threads=, "Profile#initialize", 2023, 6
106
- deprecate :start, "Profile#start", 2023, 6
107
- deprecate :pause, "Profile#pause", 2023, 6
108
- deprecate :stop, "Profile#stop", 2023, 6
109
- deprecate :resume, "Profile#resume", 2023, 6
110
- deprecate :running?, "Profile#running?", 2023, 6
111
- deprecate :profile, "Profile.profile", 2023, 6
102
+ deprecate :measure_mode, "RubyProf::Profile#measure_mode", 2023, 6
103
+ deprecate :measure_mode=, "RubyProf::Profile#measure_mode=", 2023, 6
104
+ deprecate :exclude_threads, "RubyProf::Profile#exclude_threads", 2023, 6
105
+ deprecate :exclude_threads=, "RubyProf::Profile#initialize", 2023, 6
106
+ deprecate :start, "RubyProf::Profile#start", 2023, 6
107
+ deprecate :pause, "RubyProf::Profile#pause", 2023, 6
108
+ deprecate :stop, "RubyProf::Profile#stop", 2023, 6
109
+ deprecate :resume, "RubyProf::Profile#resume", 2023, 6
110
+ deprecate :running?, "RubyProf::Profile#running?", 2023, 6
111
+ deprecate :profile, "RubyProf::Profile.profile", 2023, 6
112
112
  end
113
113
  end
@@ -22,18 +22,24 @@ module RubyProf
22
22
  # Fundamental Types
23
23
  ##
24
24
 
25
- exclude_methods(profile, BasicObject, :"!=")
26
- exclude_methods(profile, Method, :"[]")
25
+ exclude_methods(profile, BasicObject, :!=)
26
+ exclude_methods(profile, Kernel, :"block_given?")
27
+ exclude_methods(profile, Method, :[])
27
28
  exclude_methods(profile, Module, :new)
28
29
  exclude_methods(profile, Class, :new)
29
30
  exclude_methods(profile, Proc, :call, :yield)
30
31
  exclude_methods(profile, Range, :each)
31
- exclude_methods(profile, Integer, :times)
32
32
 
33
33
  ##
34
34
  # Value Types
35
35
  ##
36
36
 
37
+ exclude_methods(profile, Integer, [
38
+ :times,
39
+ :succ,
40
+ :<
41
+ ])
42
+
37
43
  exclude_methods(profile, String, [
38
44
  :sub,
39
45
  :sub!,
@@ -1,85 +1,87 @@
1
- # encoding: utf-8
2
-
3
- module RubyProf
4
- # The MethodInfo class is used to track information about each method that is profiled.
5
- # You cannot create a MethodInfo object directly, they are generated while running a profile.
6
- class MethodInfo
7
- include Comparable
8
-
9
- # Returns the full name of a class. The interpretation of method names is:
10
- #
11
- # * MyObject#test - An method defined in a class
12
- # * <Class:MyObject>#test - A method defined in a singleton class.
13
- # * <Module:MyObject>#test - A method defined in a singleton module.
14
- # * <Object:MyObject>#test - A method defined in a singleton object.
15
- def full_name
16
- decorated_class_name = case self.klass_flags
17
- when 0x2
18
- "<Class::#{klass_name}>"
19
- when 0x4
20
- "<Module::#{klass_name}>"
21
- when 0x8
22
- "<Object::#{klass_name}>"
23
- else
24
- klass_name
25
- end
26
-
27
- "#{decorated_class_name}##{method_name}"
28
- end
29
-
30
- # The number of times this method was called
31
- def called
32
- self.measurement.called
33
- end
34
-
35
- # The total time this method took - includes self time + wait time + child time
36
- def total_time
37
- self.measurement.total_time
38
- end
39
-
40
- # The time this method took to execute
41
- def self_time
42
- self.measurement.self_time
43
- end
44
-
45
- # The time this method waited for other fibers/threads to execute
46
- def wait_time
47
- self.measurement.wait_time
48
- end
49
-
50
- # The time this method's children took to execute
51
- def children_time
52
- self.total_time - self.self_time - self.wait_time
53
- end
54
-
55
- def eql?(other)
56
- self.hash == other.hash
57
- end
58
-
59
- def ==(other)
60
- self.eql?(other)
61
- end
62
-
63
- def <=>(other)
64
- if other.nil?
65
- -1
66
- elsif self.full_name == other.full_name
67
- 0
68
- elsif self.total_time < other.total_time
69
- -1
70
- elsif self.total_time > other.total_time
71
- 1
72
- elsif self.call_trees.min_depth < other.call_trees.min_depth
73
- 1
74
- elsif self.call_trees.min_depth > other.call_trees.min_depth
75
- -1
76
- else
77
- self.full_name <=> other.full_name
78
- end
79
- end
80
-
81
- def to_s
82
- "#{self.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, wt: #{wait_time}, ct: #{self.children_time})"
83
- end
84
- end
85
- end
1
+ # encoding: utf-8
2
+
3
+ module RubyProf
4
+ # The MethodInfo class is used to track information about each method that is profiled.
5
+ # You cannot create a MethodInfo object directly, they are generated while running a profile.
6
+ class MethodInfo
7
+ include Comparable
8
+
9
+ # Returns the full name of a class. The interpretation of method names is:
10
+ #
11
+ # * MyObject#test - An method defined in a class
12
+ # * <Class:MyObject>#test - A method defined in a singleton class.
13
+ # * <Module:MyObject>#test - A method defined in a singleton module.
14
+ # * <Object:MyObject>#test - A method defined in a singleton object.
15
+ def full_name
16
+ decorated_class_name = case self.klass_flags
17
+ when 0x2
18
+ "<Class::#{klass_name}>"
19
+ when 0x4
20
+ "<Module::#{klass_name}>"
21
+ when 0x8
22
+ "<Object::#{klass_name}>"
23
+ else
24
+ klass_name
25
+ end
26
+
27
+ "#{decorated_class_name}##{method_name}"
28
+ end
29
+
30
+ # The number of times this method was called
31
+ def called
32
+ self.measurement.called
33
+ end
34
+
35
+ # The total time this method took - includes self time + wait time + child time
36
+ def total_time
37
+ self.measurement.total_time
38
+ end
39
+
40
+ # The time this method took to execute
41
+ def self_time
42
+ self.measurement.self_time
43
+ end
44
+
45
+ # The time this method waited for other fibers/threads to execute
46
+ def wait_time
47
+ self.measurement.wait_time
48
+ end
49
+
50
+ # The time this method's children took to execute
51
+ def children_time
52
+ self.total_time - self.self_time - self.wait_time
53
+ end
54
+
55
+ def eql?(other)
56
+ self.hash == other.hash
57
+ end
58
+
59
+ def ==(other)
60
+ self.eql?(other)
61
+ end
62
+
63
+ def <=>(other)
64
+ sort_delta = 0.0001
65
+
66
+ if other.nil?
67
+ -1
68
+ elsif self.full_name == other.full_name
69
+ 0
70
+ elsif self.total_time < other.total_time && (self.total_time - other.total_time).abs > sort_delta
71
+ -1
72
+ elsif self.total_time > other.total_time && (self.total_time - other.total_time).abs > sort_delta
73
+ 1
74
+ elsif self.call_trees.min_depth < other.call_trees.min_depth
75
+ 1
76
+ elsif self.call_trees.min_depth > other.call_trees.min_depth
77
+ -1
78
+ else
79
+ self.full_name <=> other.full_name
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ "#{self.full_name} (c: #{self.called}, tt: #{self.total_time}, st: #{self.self_time}, wt: #{wait_time}, ct: #{self.children_time})"
85
+ end
86
+ end
87
+ end
@@ -1,3 +1,3 @@
1
1
  module RubyProf
2
- VERSION = "1.6.3"
2
+ VERSION = "1.7.0"
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.7.0'
59
+ spec.required_ruby_version = '>= 3.0.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')