ruby-prof 0.11.0.rc3 → 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,31 @@
1
+ 0.11.2 (2012-05-06)
2
+ ======================
3
+ * Fix compile issue with BOOL. Should be _Bool for C99.
4
+
5
+
6
+ 0.11.1 (2012-05-06)
7
+ ======================
8
+ * Added option --exclude-common-callbacks, plus exclude #map and #inject in common cycles (Vasily Fedoseyev)
9
+ * Add option --exclude-common-cycles to exclude common iterators (Vasily Fedoseyev)
10
+ * Allow method elimination from command line via '-x' and '-X' keys (Vasily Fedoseyev)
11
+
12
+
13
+ 0.11.0 (2012-05-05)
14
+ ======================
15
+ * Fix pause/resume so it actually works and add tests (David Barri)
16
+ * Resume now returns the result of the block when given (David Barri)
17
+ * Make recursive method explanation more clear (Charlie Savage)
18
+ * Fix ruby warnings (Charlie Savage)
19
+ * Toggle GC.enable_stats when profiling for memory to get the data (Vasily Fedoseyev)
20
+ * Fix patched ruby support and remove some warnings (Vasily Fedoseyev)
21
+ * Fix tests on 1.8.7 (rogerdpack)
22
+
23
+
24
+ 0.11.0.rc3 (2012-03-26)
25
+ ======================
26
+ * Include missing files in gemspec (Charlie Savage).
27
+
28
+
1
29
  0.11.0.rc2 (2012-03-25)
2
30
  ======================
3
31
  * Lots of improvements to Rack handler - this can be used to profile requests
data/Rakefile CHANGED
@@ -22,6 +22,7 @@ SO_NAME = 'ruby_prof'
22
22
 
23
23
  default_spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
24
24
 
25
+ # specify which versions/builds to cross compile
25
26
  Rake::ExtensionTask.new do |ext|
26
27
  ext.gem_spec = default_spec
27
28
  ext.name = SO_NAME
@@ -172,6 +172,59 @@ opts = OptionParser.new do |opts|
172
172
  options.exec ||= []
173
173
  options.exec << code
174
174
  end
175
+
176
+ opts.on('-x regexp', '--exclude regexp', 'exclude methods by regexp (see method elimination)') do|meth|
177
+ options.eliminate_methods ||= []
178
+ options.eliminate_methods << Regexp.new(meth)
179
+ end
180
+
181
+ opts.on('-X file', '--exclude-file file', 'exclude methods by regexp listed in file (see method elimination)') do|file|
182
+ options.eliminate_methods_files ||= []
183
+ options.eliminate_methods_files << file
184
+ end
185
+
186
+ opts.on('--exclude-common-cycles', 'make common iterators like Integer#times appear inlined') do|meth|
187
+ options.eliminate_methods ||= []
188
+ options.eliminate_methods += %w{
189
+ Integer#times
190
+ Integer#upto
191
+ Integer#downto
192
+ Enumerator#each
193
+ Enumerator#each_with_index
194
+ Enumerator#each_with_object
195
+
196
+ Array#each
197
+ Array#each_index
198
+ Array#reverse_each
199
+ Array#map
200
+
201
+ Hash#each
202
+ Hash#each_pair
203
+ Hash#each_key
204
+ Hash#each_value
205
+
206
+ Range#each
207
+ Enumerable#each_cons
208
+ Enumerable#each_entry
209
+ Enumerable#each_slice
210
+ Enumerable#each_with_index
211
+ Enumerable#each_with_object
212
+ Enumerable#reverse_each
213
+ Enumerable#inject
214
+ Enumerable#collect
215
+ Enumerable#reduce
216
+ }
217
+ #TODO: may be the whole Enumerable module should be excluded via 'Enumerable#.*', we need feedback on use cases.
218
+ end
219
+
220
+ opts.on('--exclude-common-callbacks', 'make common callbacks invocations like Integer#times appear inlined so you can see call origins in graph') do|meth|
221
+ options.eliminate_methods ||= []
222
+ options.eliminate_methods += %w{
223
+ Method#call
224
+ Proc#call
225
+ ActiveSupport::Callbacks::ClassMethods#__run_callback
226
+ }
227
+ end
175
228
  end
176
229
 
177
230
  begin
@@ -201,6 +254,10 @@ at_exit {
201
254
  # Stop profiling
202
255
  result = RubyProf.stop
203
256
 
257
+ # Eliminate unwanted methods from call graph
258
+ result.eliminate_methods! options.eliminate_methods if options.eliminate_methods
259
+ options.eliminate_methods_files.each{|f| result.eliminate_methods!(f)} if options.eliminate_methods_files
260
+
204
261
  # Create a printer
205
262
  printer = options.printer.new(result)
206
263
  printer_options = {:min_percent => options.min_percent, :sort_method => options.sort_method}
@@ -8,50 +8,29 @@
8
8
  static VALUE cMeasureAllocations;
9
9
 
10
10
  #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
11
- #define MEASURE_ALLOCATIONS_ENABLED Qtrue
11
+ unsigned LONG_LONG rb_os_allocated_objects();
12
+ #endif
13
+
14
+ #if defined(HAVE_RB_GC_MALLOC_ALLOCATIONS)
15
+ unsigned LONG_LONG rb_gc_malloc_allocations();
16
+ #endif
12
17
 
13
18
  static double
14
19
  measure_allocations()
15
20
  {
21
+ #if defined(HAVE_RB_OS_ALLOCATED_OBJECTS)
22
+ #define MEASURE_ALLOCATIONS_ENABLED Qtrue
16
23
  return rb_os_allocated_objects();
17
- }
18
-
19
- /* Document-method: prof_measure_allocations
20
- call-seq:
21
- measure_allocations -> int
22
-
23
- Returns the total number of object allocations since Ruby started.*/
24
- static VALUE
25
- prof_measure_allocations(VALUE self)
26
- {
27
- #if defined(HAVE_LONG_LONG)
28
- return ULL2NUM(rb_os_allocated_objects());
29
- #else
30
- return ULONG2NUM(rb_os_allocated_objects());
31
- #endif
32
- }
33
24
 
34
25
  #elif defined(HAVE_RB_GC_MALLOC_ALLOCATIONS)
35
-
36
26
  #define MEASURE_ALLOCATIONS_ENABLED Qtrue
37
-
38
- static double
39
- measure_allocations()
40
- {
41
27
  return rb_gc_malloc_allocations();
42
- }
43
28
 
44
29
  #else
45
-
46
30
  #define MEASURE_ALLOCATIONS_ENABLED Qfalse
47
-
48
- static double
49
- measure_allocations()
50
- {
51
31
  return 0;
52
- }
53
-
54
32
  #endif
33
+ }
55
34
 
56
35
 
57
36
  prof_measurer_t* prof_measurer_allocations()
@@ -8,53 +8,31 @@
8
8
  static VALUE cMeasureGcRuns;
9
9
 
10
10
  #if defined(HAVE_RB_GC_COLLECTIONS)
11
+ VALUE rb_gc_collections(void);
12
+ #endif
13
+
14
+ #if defined(HAVE_RB_GC_HEAP_INFO)
15
+ VALUE rb_gc_heap_info(void);
16
+ #endif
11
17
 
12
- #define MEASURE_GC_RUNS_ENABLED Qtrue
13
18
 
14
19
  static double
15
20
  measure_gc_runs()
16
21
  {
17
- return NUM2INT(rb_gc_collections());
18
- }
19
-
20
- /* call-seq:
21
- gc_runs -> Integer
22
-
23
- Returns the total number of garbage collections.*/
24
- static VALUE
25
- prof_measure_gc_runs(VALUE self)
26
- {
27
- return rb_gc_collections();
28
- }
22
+ #if defined(HAVE_RB_GC_COLLECTIONS)
23
+ #define MEASURE_GC_RUNS_ENABLED Qtrue
24
+ return NUM2INT(rb_gc_collections());
29
25
 
30
26
  #elif defined(HAVE_RB_GC_HEAP_INFO)
31
-
32
27
  #define MEASURE_GC_RUNS_ENABLED Qtrue
33
-
34
- static double
35
- measure_gc_runs()
36
- {
37
28
  VALUE h = rb_gc_heap_info();
38
29
  return NUM2UINT(rb_hash_aref(h, rb_str_new2("num_gc_passes")));
39
- }
40
-
41
- static VALUE
42
- prof_measure_gc_runs(VALUE self)
43
- {
44
- VALUE h = rb_gc_heap_info();
45
- return rb_hash_aref(h, rb_str_new2("num_gc_passes"));
46
- }
47
-
48
- #else
49
30
 
31
+ #else
50
32
  #define MEASURE_GC_RUNS_ENABLED Qfalse
51
-
52
- static double
53
- measure_gc_runs()
54
- {
55
33
  return 0;
56
- }
57
34
  #endif
35
+ }
58
36
 
59
37
  prof_measurer_t* prof_measurer_gc_runs()
60
38
  {
@@ -8,40 +8,27 @@
8
8
  static VALUE cMeasureGcTimes;
9
9
 
10
10
  #if defined(HAVE_RB_GC_TIME)
11
+ VALUE rb_gc_time();
12
+ #endif
11
13
 
12
- #define MEASURE_GC_TIME_ENABLED Qtrue
13
14
 
14
15
  static double
15
16
  measure_gc_time()
16
17
  {
17
- int conversion = 1000000
18
+ #if defined(HAVE_RB_GC_TIME)
19
+ #define MEASURE_GC_TIME_ENABLED Qtrue
20
+ const int conversion = 1000000;
18
21
  #if HAVE_LONG_LONG
19
22
  return NUM2LL(rb_gc_time() / conversion);
20
23
  #else
21
24
  return NUM2LONG(rb_gc_time() / conversion));
22
25
  #endif
23
- }
24
-
25
- /* call-seq:
26
- gc_time -> Integer
27
-
28
- Returns the time spent doing garbage collections in microseconds.*/
29
- static VALUE
30
- prof_measure_gc_time(VALUE self)
31
- {
32
- return rb_gc_time();
33
- }
34
26
 
35
27
  #else
36
-
37
28
  #define MEASURE_GC_TIME_ENABLED Qfalse
38
-
39
- static double
40
- measure_gc_time()
41
- {
42
29
  return 0;
43
- }
44
30
  #endif
31
+ }
45
32
 
46
33
  prof_measurer_t* prof_measurer_gc_time()
47
34
  {
@@ -63,6 +50,7 @@ prof_measure_gc_time(VALUE self)
63
50
  return ULONG2NUM(measure_gc_time());
64
51
  #endif
65
52
  }
53
+
66
54
  void rp_init_measure_gc_time()
67
55
  {
68
56
  rb_define_const(mProf, "GC_TIME", INT2NUM(MEASURE_GC_TIME));
@@ -7,52 +7,45 @@
7
7
 
8
8
  static VALUE cMeasureMemory;
9
9
 
10
+
10
11
  #if defined(HAVE_RB_GC_ALLOCATED_SIZE)
11
- #define TOGGLE_GC_STATS 1
12
- #define MEASURE_GC_TIME_ENABLED Qtrue
12
+ VALUE rb_gc_allocated_size();
13
+ #endif
14
+
15
+ #if defined(HAVE_RB_GC_MALLOC_ALLOCATED_SIZE)
16
+ size_t rb_gc_malloc_allocated_size();
17
+ #endif
18
+
19
+ #if defined(HAVE_RB_HEAP_TOTAL_MEM)
20
+ //FIXME: did not find the patch to check prototype, assuming it to return size_t
21
+ size_t rb_heap_total_mem();
22
+ #endif
13
23
 
14
24
  static double
15
25
  measure_memory()
16
26
  {
27
+ #if defined(HAVE_RB_GC_ALLOCATED_SIZE)
28
+ #define TOGGLE_GC_STATS 1
29
+ #define MEASURE_MEMORY_ENABLED Qtrue
17
30
  #if defined(HAVE_LONG_LONG)
18
- return NUM2LL(rb_gc_allocated_size() / 1024);
31
+ return NUM2LL(rb_gc_allocated_size()) / 1024.0;
19
32
  #else
20
- return NUM2ULONG(rb_gc_allocated_size() / 1024);
33
+ return NUM2ULONG(rb_gc_allocated_size()) / 1024.0;
21
34
  #endif
22
- }
23
35
 
24
36
  #elif defined(HAVE_RB_GC_MALLOC_ALLOCATED_SIZE)
25
-
26
37
  #define MEASURE_MEMORY_ENABLED Qtrue
27
-
28
- static double
29
- measure_memory()
30
- {
31
- return rb_gc_malloc_allocated_size() / 1024;
32
- }
33
-
38
+ return rb_gc_malloc_allocated_size() / 1024.0;
34
39
 
35
40
  #elif defined(HAVE_RB_HEAP_TOTAL_MEM)
36
-
37
41
  #define MEASURE_MEMORY_ENABLED Qtrue
38
-
39
- static double
40
- measure_memory()
41
- {
42
- return rb_heap_total_mem() / 1024;
43
- }
42
+ return rb_heap_total_mem() / 1024.0;
44
43
 
45
44
  #else
46
-
47
45
  #define MEASURE_MEMORY_ENABLED Qfalse
48
-
49
- static double
50
- measure_memory()
51
- {
52
46
  return 0;
53
- }
54
-
55
47
  #endif
48
+ }
56
49
 
57
50
  prof_measurer_t* prof_measurer_memory()
58
51
  {
@@ -5,6 +5,22 @@
5
5
 
6
6
  #define INITIAL_STACK_SIZE 8
7
7
 
8
+ void
9
+ frame_pause(prof_frame_t *frame, double current_measurement)
10
+ {
11
+ if (frame && frame_is_unpaused(frame))
12
+ frame->pause_time = current_measurement;
13
+ }
14
+
15
+ void
16
+ frame_unpause(prof_frame_t *frame, double current_measurement)
17
+ {
18
+ if (frame && frame_is_paused(frame)) {
19
+ frame->dead_time += (current_measurement - frame->pause_time);
20
+ frame->pause_time = -1;
21
+ }
22
+ }
23
+
8
24
 
9
25
  /* Creates a stack of prof_frame_t to keep track
10
26
  of timings for active methods. */
@@ -48,7 +64,7 @@ stack_push(prof_stack_t *stack)
48
64
  result->child_time = 0;
49
65
  result->switch_time = 0;
50
66
  result->wait_time = 0;
51
- result->depth = (stack->ptr - stack->start);
67
+ result->depth = (int)(stack->ptr - stack->start); // shortening of 64 bit into 32
52
68
 
53
69
  // Increment the stack ptr for next time
54
70
  stack->ptr++;
@@ -22,10 +22,18 @@ typedef struct
22
22
  double switch_time; /* Time at switch to different thread */
23
23
  double wait_time;
24
24
  double child_time;
25
+ double pause_time; // Time pause() was initiated
26
+ double dead_time; // Time to ignore (i.e. total amount of time between pause/resume blocks)
25
27
  int depth;
26
28
  unsigned int line;
27
29
  } prof_frame_t;
28
30
 
31
+ #define frame_is_paused(f) (f->pause_time >= 0)
32
+ #define frame_is_unpaused(f) (f->pause_time < 0)
33
+ void frame_pause(prof_frame_t*, double current_measurement);
34
+ void frame_unpause(prof_frame_t*, double current_measurement);
35
+
36
+
29
37
  /* Current stack of active methods.*/
30
38
  typedef struct
31
39
  {
@@ -133,6 +133,11 @@ pop_frame(prof_profile_t* profile, thread_data_t *thread_data)
133
133
  double measurement = profile->measurer->measure();
134
134
  double total_time;
135
135
  double self_time;
136
+ #ifdef _MSC_VER
137
+ BOOL frame_paused;
138
+ #else
139
+ _Bool frame_paused;
140
+ #endif
136
141
 
137
142
  frame = stack_pop(thread_data->stack); // only time it's called
138
143
 
@@ -140,11 +145,13 @@ pop_frame(prof_profile_t* profile, thread_data_t *thread_data)
140
145
  a method that exits. And it can happen if an exception is raised
141
146
  in code that is being profiled and the stack unwinds (RubyProf is
142
147
  not notified of that by the ruby runtime. */
143
- if (frame == NULL)
148
+ if (frame == NULL)
144
149
  return NULL;
145
150
 
146
151
  /* Calculate the total time this method took */
147
- total_time = measurement - frame->start_time;
152
+ frame_paused = frame_is_paused(frame);
153
+ frame_unpause(frame, measurement);
154
+ total_time = measurement - frame->start_time - frame->dead_time;
148
155
  self_time = total_time - frame->child_time - frame->wait_time;
149
156
 
150
157
  /* Update information about the current method */
@@ -158,6 +165,12 @@ pop_frame(prof_profile_t* profile, thread_data_t *thread_data)
158
165
  if (parent_frame)
159
166
  {
160
167
  parent_frame->child_time += total_time;
168
+ parent_frame->dead_time += frame->dead_time;
169
+
170
+ // Repause parent if currently paused
171
+ if (frame_paused)
172
+ frame_pause(parent_frame, measurement);
173
+
161
174
  call_info->line = parent_frame->line;
162
175
  }
163
176
 
@@ -333,6 +346,11 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
333
346
  call_info_table_insert(frame->call_info->call_infos, method->key, call_info);
334
347
  prof_add_call_info(method->call_infos, call_info);
335
348
  }
349
+
350
+ // Unpause the parent frame. If currently paused then:
351
+ // 1) The child frame will begin paused.
352
+ // 2) The parent will inherit the child's dead time.
353
+ frame_unpause(frame, measurement);
336
354
  }
337
355
 
338
356
  /* Push a new frame onto the stack for a new c-call or ruby call (into a method) */
@@ -340,6 +358,8 @@ prof_event_hook(rb_event_flag_t event, NODE *node, VALUE self, ID mid, VALUE kla
340
358
  frame->call_info = call_info;
341
359
  frame->call_info->depth = frame->depth;
342
360
  frame->start_time = measurement;
361
+ frame->pause_time = profile->paused == Qtrue ? measurement : -1;
362
+ frame->dead_time = 0;
343
363
  frame->line = rb_sourceline();
344
364
  break;
345
365
  }
@@ -459,7 +479,7 @@ prof_initialize(int argc, VALUE *argv, VALUE self)
459
479
  {
460
480
  prof_profile_t* profile = prof_get_profile(self);
461
481
  VALUE mode;
462
- prof_measure_mode_t measurer;
482
+ prof_measure_mode_t measurer = MEASURE_WALL_TIME;
463
483
  VALUE exclude_threads;
464
484
  int i;
465
485
 
@@ -497,6 +517,39 @@ prof_initialize(int argc, VALUE *argv, VALUE self)
497
517
  return self;
498
518
  }
499
519
 
520
+ static int pause_thread(st_data_t key, st_data_t value, st_data_t data)
521
+ {
522
+ thread_data_t* thread_data = (thread_data_t *) value;
523
+ prof_profile_t* profile = (prof_profile_t*) data;
524
+
525
+ prof_frame_t* frame = stack_peek(thread_data->stack);
526
+ frame_pause(frame, profile->measurement_at_pause_resume);
527
+
528
+ return ST_CONTINUE;
529
+ }
530
+
531
+ static int unpause_thread(st_data_t key, st_data_t value, st_data_t data)
532
+ {
533
+ thread_data_t* thread_data = (thread_data_t *) value;
534
+ prof_profile_t* profile = (prof_profile_t*) data;
535
+
536
+ prof_frame_t* frame = stack_peek(thread_data->stack);
537
+ frame_unpause(frame, profile->measurement_at_pause_resume);
538
+
539
+ return ST_CONTINUE;
540
+ }
541
+
542
+ /* call-seq:
543
+ paused? -> boolean
544
+
545
+ Returns whether a profile is currently paused.*/
546
+ static VALUE
547
+ prof_paused(VALUE self)
548
+ {
549
+ prof_profile_t* profile = prof_get_profile(self);
550
+ return profile->paused;
551
+ }
552
+
500
553
  /* call-seq:
501
554
  running? -> boolean
502
555
 
@@ -516,6 +569,7 @@ static VALUE
516
569
  prof_start(VALUE self)
517
570
  {
518
571
  char* trace_file_name;
572
+
519
573
  prof_profile_t* profile = prof_get_profile(self);
520
574
 
521
575
  if (profile->running == Qtrue)
@@ -523,7 +577,15 @@ prof_start(VALUE self)
523
577
  rb_raise(rb_eRuntimeError, "RubyProf.start was already called");
524
578
  }
525
579
 
580
+ #ifndef RUBY_VM
581
+ if (pCurrentProfile != NULL)
582
+ {
583
+ rb_raise(rb_eRuntimeError, "Only one profile can run at a time on Ruby 1.8.*");
584
+ }
585
+ #endif
586
+
526
587
  profile->running = Qtrue;
588
+ profile->paused = Qfalse;
527
589
  profile->last_thread_data = NULL;
528
590
 
529
591
 
@@ -562,9 +624,13 @@ prof_pause(VALUE self)
562
624
  rb_raise(rb_eRuntimeError, "RubyProf is not running.");
563
625
  }
564
626
 
565
- profile->running = Qfalse;
627
+ if (profile->paused == Qfalse)
628
+ {
629
+ profile->paused = Qtrue;
630
+ profile->measurement_at_pause_resume = profile->measurer->measure();
631
+ st_foreach(profile->threads_tbl, pause_thread, (st_data_t) profile);
632
+ }
566
633
 
567
- prof_remove_hook();
568
634
  return self;
569
635
  }
570
636
 
@@ -578,20 +644,17 @@ prof_resume(VALUE self)
578
644
  prof_profile_t* profile = prof_get_profile(self);
579
645
  if (profile->running == Qfalse)
580
646
  {
581
- prof_start(self);
582
- }
583
- else
584
- {
585
- profile->running = Qtrue;
586
- prof_install_hook(self);
647
+ rb_raise(rb_eRuntimeError, "RubyProf is not running.");
587
648
  }
588
649
 
589
- if (rb_block_given_p())
650
+ if (profile->paused == Qtrue)
590
651
  {
591
- rb_ensure(rb_yield, self, prof_pause, self);
652
+ profile->paused = Qfalse;
653
+ profile->measurement_at_pause_resume = profile->measurer->measure();
654
+ st_foreach(profile->threads_tbl, unpause_thread, (st_data_t) profile);
592
655
  }
593
656
 
594
- return self;
657
+ return rb_block_given_p() ? rb_ensure(rb_yield, self, prof_pause, self) : self;
595
658
  }
596
659
 
597
660
  /* call-seq:
@@ -628,7 +691,7 @@ prof_stop(VALUE self)
628
691
 
629
692
  /* Unset the last_thread_data (very important!)
630
693
  and the threads table */
631
- profile->running = Qfalse;
694
+ profile->running = profile->paused = Qfalse;
632
695
  profile->last_thread_data = NULL;
633
696
 
634
697
  /* Post process result */
@@ -686,10 +749,10 @@ void Init_ruby_prof()
686
749
  rb_define_alloc_func (cProfile, prof_allocate);
687
750
  rb_define_method(cProfile, "initialize", prof_initialize, -1);
688
751
  rb_define_method(cProfile, "start", prof_start, 0);
689
- rb_define_method(cProfile, "start", prof_start, 0);
690
752
  rb_define_method(cProfile, "stop", prof_stop, 0);
691
753
  rb_define_method(cProfile, "resume", prof_resume, 0);
692
754
  rb_define_method(cProfile, "pause", prof_pause, 0);
693
755
  rb_define_method(cProfile, "running?", prof_running, 0);
756
+ rb_define_method(cProfile, "paused?", prof_paused, 0);
694
757
  rb_define_method(cProfile, "threads", prof_threads, 0);
695
758
  }
@@ -42,11 +42,13 @@ void method_key(prof_method_key_t* key, VALUE klass, ID mid);
42
42
  typedef struct
43
43
  {
44
44
  VALUE running;
45
+ VALUE paused;
45
46
  prof_measurer_t* measurer;
46
47
  VALUE threads;
47
48
  st_table* threads_tbl;
48
49
  st_table* exclude_threads_tbl;
49
50
  thread_data_t* last_thread_data;
51
+ double measurement_at_pause_resume;
50
52
  } prof_profile_t;
51
53
 
52
54
 
@@ -64,6 +64,8 @@
64
64
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
65
65
  <LinkIncremental>true</LinkIncremental>
66
66
  <OutDir>C:\MinGW\local\src\ruby-prof\lib\1.8</OutDir>
67
+ <TargetExt>.so</TargetExt>
68
+ <TargetName>ruby_prof</TargetName>
67
69
  </PropertyGroup>
68
70
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
69
71
  <LinkIncremental>false</LinkIncremental>
@@ -81,6 +83,7 @@
81
83
  <GenerateDebugInformation>true</GenerateDebugInformation>
82
84
  <AdditionalLibraryDirectories>C:\MinGW\local\ruby187vc\lib</AdditionalLibraryDirectories>
83
85
  <AdditionalDependencies>msvcr100-ruby18.lib;%(AdditionalDependencies)</AdditionalDependencies>
86
+ <ModuleDefinitionFile>ruby_prof.def</ModuleDefinitionFile>
84
87
  </Link>
85
88
  </ItemDefinitionGroup>
86
89
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -1,7 +1,7 @@
1
1
  /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
- #define RUBY_PROF_VERSION "0.11.0" // for easy parsing from rake files
4
+ #define RUBY_PROF_VERSION "0.11.2" // for easy parsing from rake files
5
5
  #define RUBY_PROF_VERSION_MAJ 0
6
6
  #define RUBY_PROF_VERSION_MIN 11
7
- #define RUBY_PROF_VERSION_MIC 0
7
+ #define RUBY_PROF_VERSION_MIC 2
@@ -18,7 +18,7 @@ module RubyProf
18
18
  def self.measure_cpu_time
19
19
  Measure::CpuTime.measure
20
20
  end
21
-
21
+
22
22
  def self.measure_gc_runs
23
23
  Measure::GcRuns.measure
24
24
  end
@@ -38,7 +38,7 @@ module RubyProf
38
38
  def self.measure_wall_time
39
39
  Measure::WallTime.measure
40
40
  end
41
-
41
+
42
42
  # call-seq:
43
43
  # measure_mode -> measure_mode
44
44
  #
@@ -51,11 +51,11 @@ module RubyProf
51
51
  # *RubyProf::MEMORY - Measure memory size. This requires a patched Ruby interpreter.
52
52
  # *RubyProf::GC_RUNS - Measure number of garbage collections. This requires a patched Ruby interpreter.
53
53
  # *RubyProf::GC_TIME - Measure time spent doing garbage collection. This requires a patched Ruby interpreter.*/
54
-
54
+
55
55
  def self.measure_mode
56
56
  @measure_mode ||= RubyProf::WALL_TIME
57
57
  end
58
-
58
+
59
59
  # call-seq:
60
60
  # measure_mode=value -> void
61
61
  #
@@ -71,33 +71,31 @@ module RubyProf
71
71
  def self.measure_mode=(value)
72
72
  @measure_mode = value
73
73
  end
74
-
74
+
75
75
  # call-seq:
76
76
  # exclude_threads= -> void
77
77
  #
78
78
  # Specifies what threads ruby-prof should exclude from profiling
79
-
79
+
80
80
  def self.exclude_threads
81
81
  @exclude_threads ||= Array.new
82
82
  end
83
-
83
+
84
84
  def self.exclude_threads=(value)
85
85
  @exclude_threads = value
86
86
  end
87
-
87
+
88
88
  # Profiling
89
89
  def self.start
90
- if running?
91
- raise(RuntimeError, "RubyProf is already running");
92
- end
90
+ ensure_not_running!
93
91
  @profile = Profile.new(self.measure_mode, self.exclude_threads)
92
+ enable_gc_stats_if_needed
94
93
  @profile.start
95
94
  end
96
95
 
97
96
  def self.pause
98
- unless running?
99
- raise(RuntimeError, "RubyProf.start was not yet called");
100
- end
97
+ ensure_running!
98
+ disable_gc_stats_if_needed
101
99
  @profile.pause
102
100
  end
103
101
 
@@ -110,25 +108,47 @@ module RubyProf
110
108
  end
111
109
 
112
110
  def self.resume
113
- unless running?
114
- raise(RuntimeError, "RubyProf.start was not yet called");
115
- end
111
+ ensure_running!
112
+ enable_gc_stats_if_needed
116
113
  @profile.resume
117
114
  end
118
115
 
119
116
  def self.stop
120
- unless running?
121
- raise(RuntimeError, "RubyProf.start was not yet called");
122
- end
117
+ ensure_running!
118
+ disable_gc_stats_if_needed
123
119
  result = @profile.stop
124
120
  @profile = nil
125
121
  result
126
122
  end
127
123
 
124
+ # Profile a block
128
125
  def self.profile(&block)
129
- if running?
130
- raise(RuntimeError, "RubyProf is already running");
126
+ ensure_not_running!
127
+ gc_stat_was_enabled = enable_gc_stats_if_needed
128
+ res = Profile.profile(self.measure_mode, self.exclude_threads, &block)
129
+ disable_gc_stats_if_needed(gc_stat_was_enabled)
130
+ res
131
+ end
132
+
133
+
134
+ private
135
+ def self.ensure_running!
136
+ raise(RuntimeError, "RubyProf.start was not yet called") unless running?
137
+ end
138
+
139
+ def self.ensure_not_running!
140
+ raise(RuntimeError, "RubyProf is already running") if running?
141
+ end
142
+
143
+ # for GC.allocated_size to work GC statistics should be enabled
144
+ def self.enable_gc_stats_if_needed
145
+ if self.measure_mode == RubyProf::MEMORY && GC.respond_to?(:enable_stats)
146
+ @gc_stat_was_enabled = GC.enable_stats
131
147
  end
132
- Profile.profile(self.measure_mode, self.exclude_threads, &block)
148
+ end
149
+
150
+ def self.disable_gc_stats_if_needed(was_enabled=nil)
151
+ was_enabled ||= defined?(@gc_stat_was_enabled) && @gc_stat_was_enabled
152
+ GC.disable_stats if self.measure_mode == RubyProf::MEMORY && GC.respond_to?(:disable_stats) && !was_enabled
133
153
  end
134
154
  end
@@ -62,7 +62,7 @@ module RubyProf
62
62
 
63
63
  def print_footer(thread)
64
64
  @output << "\n"
65
- @output << "* in front of method name means it is recursively called\n"
65
+ @output << "* indicates recursively called methods\n"
66
66
  end
67
67
  end
68
68
  end
@@ -235,7 +235,7 @@ module RubyProf
235
235
  </tbody>
236
236
  <tfoot>
237
237
  <tr>
238
- <td colspan="9">* in front of method name means it is recursively called</td>
238
+ <td colspan="9">* indicates recursively called methods</td>
239
239
  </tr>
240
240
  </tfoot>
241
241
  </table>
@@ -109,7 +109,7 @@ module RubyProf
109
109
 
110
110
  def print_footer(thread)
111
111
  @output << "\n"
112
- @output << "* in front of method name means it is recursively called\n"
112
+ @output << "* indicates recursively called methods\n"
113
113
  end
114
114
  end
115
115
  end
@@ -6,8 +6,7 @@ version_header = File.read(File.expand_path('../ext/ruby_prof/version.h', __FILE
6
6
  match = version_header.match(/RUBY_PROF_VERSION\s*"([^"]+)"/)
7
7
  raise(RuntimeError, "Could not determine RUBY_PROF_VERSION") if not match
8
8
 
9
- # For now make this an rc1
10
- RUBY_PROF_VERSION = "#{match[1]}.rc3"
9
+ RUBY_PROF_VERSION = "#{match[1]}"
11
10
 
12
11
  Gem::Specification.new do |spec|
13
12
  spec.name = "ruby-prof"
@@ -39,4 +39,58 @@ class BasicTest < Test::Unit::TestCase
39
39
 
40
40
  RubyProf.stop
41
41
  end
42
- end
42
+
43
+ def test_pause_seq
44
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
45
+ p.start ; assert !p.paused?
46
+ p.pause ; assert p.paused?
47
+ p.resume; assert !p.paused?
48
+ p.pause ; assert p.paused?
49
+ p.pause ; assert p.paused?
50
+ p.resume; assert !p.paused?
51
+ p.resume; assert !p.paused?
52
+ p.stop ; assert !p.paused?
53
+ end
54
+
55
+ def test_pause_block
56
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
57
+ p.start
58
+ p.pause
59
+ assert p.paused?
60
+
61
+ times_block_invoked = 0
62
+ retval= p.resume{
63
+ times_block_invoked += 1
64
+ 120 + times_block_invoked
65
+ }
66
+ assert_equal 1, times_block_invoked
67
+ assert p.paused?
68
+
69
+ assert_equal 121, retval, "resume() should return the result of the given block."
70
+
71
+ p.stop
72
+ end
73
+
74
+ def test_pause_block_with_error
75
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
76
+ p.start
77
+ p.pause
78
+ assert p.paused?
79
+
80
+ begin
81
+ p.resume{ raise }
82
+ flunk 'Exception expected.'
83
+ rescue
84
+ assert p.paused?
85
+ end
86
+
87
+ p.stop
88
+ end
89
+
90
+ def test_resume_when_not_paused
91
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
92
+ p.start ; assert !p.paused?
93
+ p.resume; assert !p.paused?
94
+ p.stop ; assert !p.paused?
95
+ end
96
+ end
@@ -5,11 +5,9 @@ require File.expand_path('../test_helper', __FILE__)
5
5
 
6
6
  class LineNumbers
7
7
  def method1
8
- 3
9
8
  end
10
9
 
11
10
  def method2
12
- 3
13
11
  method1
14
12
  end
15
13
 
@@ -32,11 +30,11 @@ class LineNumbersTest < Test::Unit::TestCase
32
30
 
33
31
  method = methods[0]
34
32
  assert_equal('LineNumbersTest#test_function_line_no', method.full_name)
35
- assert_equal(27, method.line)
33
+ assert_equal(25, method.line)
36
34
 
37
35
  method = methods[1]
38
36
  assert_equal('LineNumbers#method2', method.full_name)
39
- assert_equal(11, method.line)
37
+ assert_equal(10, method.line)
40
38
 
41
39
  method = methods[2]
42
40
  assert_equal('LineNumbers#method1', method.full_name)
@@ -64,10 +62,10 @@ class LineNumbersTest < Test::Unit::TestCase
64
62
 
65
63
  method = methods[1]
66
64
  assert_equal('LineNumbers#method3', method.full_name)
67
- assert_equal(16, method.line)
65
+ assert_equal(14, method.line)
68
66
 
69
67
  method = methods[2]
70
68
  assert_equal('LineNumbersTest#test_c_function', method.full_name)
71
- assert_equal(50, method.line)
69
+ assert_equal(48, method.line)
72
70
  end
73
71
  end
@@ -23,9 +23,6 @@ class MeasureCpuTimeTest < Test::Unit::TestCase
23
23
  RubyProf::C1.hello
24
24
  end
25
25
 
26
- printer = RubyProf::FlatPrinter.new(result)
27
- printer.print
28
-
29
26
  # Length should be 3:
30
27
  # MeasureCpuTimeTest#test_class_methods
31
28
  # <Class::RubyProf::C1>#hello
@@ -57,7 +57,6 @@ class MultiPrinterTest < Test::Unit::TestCase
57
57
  \s*</table>')
58
58
  assert graph =~ re
59
59
  display_time = $1.to_f
60
- difference = (expected_time-display_time).abs
61
60
  assert_in_delta expected_time, display_time, 0.005
62
61
  end
63
62
 
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class PauseResumeTest < Test::Unit::TestCase
7
+
8
+ # pause/resume in the same frame
9
+ def test_pause_resume_1
10
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
11
+
12
+ p.start
13
+ method_1a
14
+
15
+ p.pause
16
+ method_1b
17
+
18
+ p.resume
19
+ method_1c
20
+
21
+ r= p.stop
22
+ assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
23
+ end
24
+ def method_1a; sleep 0.2 end
25
+ def method_1b; sleep 1 end
26
+ def method_1c; sleep 0.4 end
27
+
28
+ # pause in parent frame, resume in child
29
+ def test_pause_resume_2
30
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
31
+
32
+ p.start
33
+ method_2a
34
+
35
+ p.pause
36
+ sleep 0.5
37
+ method_2b(p)
38
+
39
+ r= p.stop
40
+ assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
41
+ end
42
+ def method_2a; sleep 0.2 end
43
+ def method_2b(p); sleep 0.5; p.resume; sleep 0.4 end
44
+
45
+ # pause in child frame, resume in parent
46
+ def test_pause_resume_3
47
+ p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
48
+
49
+ p.start
50
+ method_3a(p)
51
+
52
+ sleep 0.5
53
+ p.resume
54
+ method_3b
55
+
56
+ r= p.stop
57
+ assert_in_delta(0.6, r.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
58
+ end
59
+ def method_3a(p); sleep 0.2; p.pause; sleep 0.5 end
60
+ def method_3b; sleep 0.4 end
61
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class PauseTest < Test::Unit::TestCase
7
+ def setup
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+ end
11
+
12
+ def test_pause_resume
13
+ RubyProf.start
14
+ # Measured
15
+ RubyProf::C1.hello
16
+ RubyProf.pause
17
+
18
+ # Not measured
19
+ RubyProf::C1.hello
20
+
21
+ RubyProf.resume
22
+ # Measured
23
+ RubyProf::C1.hello
24
+ result = RubyProf.stop
25
+
26
+ printer = RubyProf::FlatPrinter.new(result)
27
+ printer.print
28
+
29
+ # Length should be 3:
30
+ # PauseTest#test_pause_resume
31
+ # <Class::RubyProf::C1>#hello
32
+ # Kernel#sleep
33
+
34
+ methods = result.threads.first.methods.sort.reverse
35
+ assert_equal(3, methods.length)
36
+
37
+ # Check the names
38
+ assert_equal('PauseTest#test_pause_resume', methods[0].full_name)
39
+ assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
40
+ assert_equal('Kernel#sleep', methods[2].full_name)
41
+
42
+ # Check times
43
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
44
+ assert_in_delta(0, methods[0].wait_time, 0.01)
45
+ assert_in_delta(0, methods[0].self_time, 0.01)
46
+
47
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
48
+ assert_in_delta(0, methods[1].wait_time, 0.01)
49
+ assert_in_delta(0, methods[1].self_time, 0.01)
50
+
51
+ assert_in_delta(0.1, methods[2].total_time, 0.01)
52
+ assert_in_delta(0, methods[2].wait_time, 0.01)
53
+ assert_in_delta(0.1, methods[2].self_time, 0.01)
54
+
55
+ end
56
+
57
+ end
@@ -51,5 +51,5 @@ def run_primes(length=10, maxnum=1000)
51
51
  primes = find_primes(random_array)
52
52
 
53
53
  # Find the largest primes
54
- # largest = find_largest(primes)
54
+ largest = find_largest(primes)
55
55
  end
@@ -6,7 +6,7 @@ require File.expand_path('../test_helper', __FILE__)
6
6
  # -- Tests ----
7
7
  class PrimeTest< Test::Unit::TestCase
8
8
  def test_consistency
9
- result = RubyProf.profile do
9
+ RubyProf.profile do
10
10
  run_primes
11
11
  end
12
12
  end
@@ -50,9 +50,10 @@ class RecursiveTest < Test::Unit::TestCase
50
50
  method.full_name.match(/Fixnum/)
51
51
  end
52
52
 
53
- assert_equal(3, methods.length) # which don't show up in 1.9
53
+ assert_equal(3, methods.length)
54
54
 
55
55
  # Method 0: RecursiveTest#test_simple
56
+ methods.sort!.reverse!
56
57
  method = methods[0]
57
58
  assert_equal('RecursiveTest#test_simple', method.full_name)
58
59
  assert_equal(1, method.called)
@@ -79,16 +80,12 @@ class RecursiveTest < Test::Unit::TestCase
79
80
  assert_equal(2, method.call_infos.length)
80
81
 
81
82
  call_info = method.call_infos.first
82
- if RUBY_VERSION < '1.9'
83
- assert_equal(4, call_info.children.length)
84
- else
85
- assert_equal(2, call_info.children.length)
86
- end
83
+ assert_equal(2 + (RUBY_VERSION < '1.9.0' ? 2 : 0), call_info.children.length)
87
84
  assert_equal('RecursiveTest#test_simple->Object#simple', call_info.call_sequence)
88
85
  assert(!call_info.recursive)
89
86
 
90
87
  call_info = method.call_infos.last
91
- assert_equal(1, call_info.children.length)
88
+ assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 2 : 0), call_info.children.length)
92
89
  assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple', call_info.call_sequence)
93
90
  assert(call_info.recursive)
94
91
 
@@ -112,6 +109,7 @@ class RecursiveTest < Test::Unit::TestCase
112
109
  assert(!call_info.recursive)
113
110
 
114
111
  if RUBY_VERSION < '1.9'
112
+ methods = result.threads.first.methods.dup.sort!.reverse!
115
113
  method = methods[3]
116
114
  assert_equal('Fixnum#-', method.full_name)
117
115
  assert_equal(2, method.called)
@@ -207,7 +205,7 @@ class RecursiveTest < Test::Unit::TestCase
207
205
 
208
206
  call_info = method.call_infos[1]
209
207
  assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times', call_info.call_sequence)
210
- assert_equal(1, call_info.children.length)
208
+ assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
211
209
  assert(call_info.recursive)
212
210
 
213
211
  method = methods[3]
@@ -221,17 +219,17 @@ class RecursiveTest < Test::Unit::TestCase
221
219
  assert_equal(3, method.call_infos.length)
222
220
  call_info = method.call_infos[0]
223
221
  assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial', call_info.call_sequence)
224
- assert_equal(3, call_info.children.length)
222
+ assert_equal(3 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
225
223
  assert(!call_info.recursive)
226
224
 
227
225
  call_info = method.call_infos[1]
228
226
  assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Object#render_partial', call_info.call_sequence)
229
- assert_equal(1, call_info.children.length)
227
+ assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
230
228
  assert(call_info.recursive)
231
229
 
232
230
  call_info = method.call_infos[2]
233
231
  assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times->Object#render_partial', call_info.call_sequence)
234
- assert_equal(1, call_info.children.length)
232
+ assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
235
233
  assert(call_info.recursive)
236
234
 
237
235
  method = methods[4]
@@ -24,6 +24,7 @@ require File.expand_path("../test_helper", __FILE__)
24
24
  module_test
25
25
  multi_printer_test
26
26
  no_method_class_test
27
+ pause_test
27
28
  prime_test
28
29
  printers_test
29
30
  recursive_test
@@ -34,5 +35,4 @@ require File.expand_path("../test_helper", __FILE__)
34
35
  thread_test
35
36
  unique_call_path_test).each do |test|
36
37
  require File.expand_path("../#{test}", __FILE__)
37
- end
38
-
38
+ end
@@ -25,14 +25,14 @@ class ThreadTest < Test::Unit::TestCase
25
25
 
26
26
  def test_thread_identity
27
27
  RubyProf.start
28
- thread = Thread.new do
28
+ sleep_thread = Thread.new do
29
29
  sleep(1)
30
30
  end
31
- thread.join
31
+ sleep_thread.join
32
32
  result = RubyProf.stop
33
33
 
34
34
  thread_ids = result.threads.map {|thread| thread.id}.sort
35
- threads = [Thread.current, thread]
35
+ threads = [Thread.current, sleep_thread]
36
36
  assert_equal(2, result.threads.length)
37
37
 
38
38
  assert(thread_ids.include?(threads[0].object_id))
@@ -164,9 +164,9 @@ class ThreadTest < Test::Unit::TestCase
164
164
  end
165
165
 
166
166
  def test_thread
167
- result = RubyProf.profile do
167
+ RubyProf.profile do
168
168
  begin
169
- status = Timeout::timeout(2) do
169
+ Timeout::timeout(2) do
170
170
  while true
171
171
  next
172
172
  end
@@ -17,7 +17,6 @@ class UniqueCallPath
17
17
  end
18
18
 
19
19
  def method_c
20
- c = 3
21
20
  end
22
21
 
23
22
  def method_k(i)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-prof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0.rc3
5
- prerelease: 7
4
+ version: 0.11.2
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Shugo Maeda, Charlie Savage, Roger Pack, Stefan Kaes
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-26 00:00:00.000000000 Z
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -137,6 +137,8 @@ files:
137
137
  - test/module_test.rb
138
138
  - test/multi_printer_test.rb
139
139
  - test/no_method_class_test.rb
140
+ - test/pause_resume_test.rb
141
+ - test/pause_test.rb
140
142
  - test/prime.rb
141
143
  - test/prime_test.rb
142
144
  - test/printers_test.rb
@@ -145,7 +147,6 @@ files:
145
147
  - test/stack_printer_test.rb
146
148
  - test/stack_test.rb
147
149
  - test/start_stop_test.rb
148
- - test/summarize_test.rb
149
150
  - test/test_helper.rb
150
151
  - test/test_suite.rb
151
152
  - test/thread_test.rb
@@ -165,12 +166,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
166
  required_rubygems_version: !ruby/object:Gem::Requirement
166
167
  none: false
167
168
  requirements:
168
- - - ! '>'
169
+ - - ! '>='
169
170
  - !ruby/object:Gem::Version
170
- version: 1.3.1
171
+ version: '0'
171
172
  requirements: []
172
173
  rubyforge_project:
173
- rubygems_version: 1.8.21
174
+ rubygems_version: 1.8.24
174
175
  signing_key:
175
176
  specification_version: 3
176
177
  summary: Fast Ruby profiler
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- def slow
7
- sleep(3)
8
- end
9
-
10
- def fast
11
- sleep(3)
12
- end
13
-
14
- def slow_caller
15
- 1.times do
16
- slow
17
- end
18
- end
19
-
20
- def fast_caller
21
- 1.times do
22
- fast
23
- end
24
- end
25
-
26
- def parent
27
- [1..10].each do
28
- #slow_caller
29
- fast_caller
30
- end
31
- end
32
-
33
- class SummarizeTest < Test::Unit::TestCase
34
- def setup
35
- # Need to use wall time for this test due to the sleep calls
36
- RubyProf::measure_mode = RubyProf::WALL_TIME
37
- end
38
-
39
- def test
40
- result = RubyProf::Profile.profile do
41
- parent
42
- end
43
-
44
- printer = RubyProf::GraphPrinter.new(result)
45
- printer.print(STDOUT)
46
-
47
- end
48
- end