[前][次][番号順一覧][スレッド一覧]

ruby-changes:25291

From: eregon <ko1@a...>
Date: Sat, 27 Oct 2012 23:36:42 +0900 (JST)
Subject: [ruby-changes:25291] eregon:r37343 (trunk): * gc.c (gc_profile_result, gc_profile_report): use internal structures

eregon	2012-10-27 23:36:22 +0900 (Sat, 27 Oct 2012)

  New Revision: 37343

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37343

  Log:
    * gc.c (gc_profile_result, gc_profile_report): use internal structures
      to avoid allocations and progressively print the output for #report.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37342)
+++ ChangeLog	(revision 37343)
@@ -1,3 +1,8 @@
+Sat Oct 27 23:33:41 2012  Benoit Daloze  <eregontp@g...>
+
+	* gc.c (gc_profile_result, gc_profile_report): use internal structures
+	  to avoid allocations and progressively print the output for #report.
+
 Sat Oct 27 11:01:10 2012  Koichi Sasada  <ko1@a...>
 
 	* numeric.c (rb_float_new_in_heap), include/ruby/ruby.h: 
Index: gc.c
===================================================================
--- gc.c	(revision 37342)
+++ gc.c	(revision 37343)
@@ -4141,69 +4141,65 @@
     return gc_profile;
 }
 
-/*
- *  call-seq:
- *     GC::Profiler.result -> String
- *
- *  Returns a profile data report such as:
- *
- *    GC 1 invokes.
- *    Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
- *        1               0.012               159240               212940                10647         0.00000000000001530000
- */
-
-static VALUE
-gc_profile_result(void)
+static void
+gc_profile_dump_on(VALUE out, VALUE (*append)(VALUE, VALUE))
 {
     rb_objspace_t *objspace = &rb_objspace;
-    VALUE record;
-    VALUE result;
-    int i, index;
+    size_t count = objspace->profile.count;
 
-    record = gc_profile_record_get();
-    if (objspace->profile.run && objspace->profile.count) {
-	result = rb_sprintf("GC %d invokes.\n", NUM2INT(gc_count(0)));
-        index = 1;
-	rb_str_cat2(result, "Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC Time(ms)\n");
-	for (i = 0; i < (int)RARRAY_LEN(record); i++) {
-	    VALUE r = RARRAY_PTR(record)[i];
+    if (objspace->profile.run && count) {
+	int index = 1;
+	size_t i;
+	gc_profile_record r;
+	append(out, rb_sprintf("GC %zu invokes.\n", objspace->count));
+	append(out, rb_str_new_cstr("Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC Time(ms)\n"));
+	for (i = 0; i < count; i++) {
+	    r = objspace->profile.record[i];
 #if !GC_PROFILE_MORE_DETAIL
-            if (rb_hash_aref(r, ID2SYM(rb_intern("GC_IS_MARKED")))) {
+            if (r.is_marked) {
 #endif
-	    rb_str_catf(result, "%5d %19.3f %20"PRIuSIZE" %20"PRIuSIZE" %20"PRIuSIZE" %30.20f\n",
-			index++, NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_INVOKE_TIME")))),
-			(size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SIZE")))),
-			(size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_SIZE")))),
-			(size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_TOTAL_OBJECTS")))),
-			NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_TIME"))))*1000);
+		append(out, rb_sprintf("%5d %19.3f %20zu %20zu %20zu %30.20f\n",
+			index++, r.gc_invoke_time, r.heap_use_size,
+			r.heap_total_size, r.heap_total_objects, r.gc_time*1000));
 #if !GC_PROFILE_MORE_DETAIL
             }
 #endif
 	}
 #if GC_PROFILE_MORE_DETAIL
-	rb_str_cat2(result, "\n\n");
-	rb_str_cat2(result, "More detail.\n");
-	rb_str_cat2(result, "Index Allocate Increase    Allocate Limit  Use Slot  Have Finalize             Mark Time(ms)            Sweep Time(ms)\n");
+	append(out, rb_str_new_cstr("\n\n" \
+		"More detail.\n" \
+		"Index Allocate Increase    Allocate Limit  Use Slot  Have Finalize             Mark Time(ms)            Sweep Time(ms)\n"));
         index = 1;
-	for (i = 0; i < (int)RARRAY_LEN(record); i++) {
-	    VALUE r = RARRAY_PTR(record)[i];
-	    rb_str_catf(result, "%5d %17"PRIuSIZE" %17"PRIuSIZE" %9"PRIuSIZE" %14s %25.20f %25.20f\n",
-			index++, (size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_INCREASE")))),
-			(size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("ALLOCATE_LIMIT")))),
-			(size_t)NUM2SIZET(rb_hash_aref(r, ID2SYM(rb_intern("HEAP_USE_SLOTS")))),
-			rb_hash_aref(r, ID2SYM(rb_intern("HAVE_FINALIZE")))? "true" : "false",
-			NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_MARK_TIME"))))*1000,
-			NUM2DBL(rb_hash_aref(r, ID2SYM(rb_intern("GC_SWEEP_TIME"))))*1000);
+	for (i = 0; i < count; i++) {
+	    r = objspace->profile.record[i];
+	    append(out, rb_sprintf("%5d %17zu %17zu %9zu %14s %25.20f %25.20f\n",
+			index++, r.allocate_increase, r.allocate_limit,
+			r.heap_use_slots, (r.have_finalize ? "true" : "false"),
+			r.gc_mark_time*1000, r.gc_sweep_time*1000));
 	}
 #endif
     }
-    else {
-	result = rb_str_new2("");
-    }
-    return result;
 }
 
+/*
+ *  call-seq:
+ *     GC::Profiler.result -> String
+ *
+ *  Returns a profile data report such as:
+ *
+ *    GC 1 invokes.
+ *    Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
+ *        1               0.012               159240               212940                10647         0.00000000000001530000
+ */
 
+static VALUE
+gc_profile_result(void)
+{
+	VALUE str = rb_str_buf_new(0);
+	gc_profile_dump_on(str, rb_str_buf_append);
+	return str;
+}
+
 /*
  *  call-seq:
  *     GC::Profiler.report
@@ -4224,7 +4220,7 @@
     else {
 	rb_scan_args(argc, argv, "01", &out);
     }
-    rb_io_write(out, gc_profile_result());
+    gc_profile_dump_on(out, rb_io_write);
 
     return Qnil;
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]