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

ruby-changes:25524

From: nobu <ko1@a...>
Date: Fri, 9 Nov 2012 16:08:48 +0900 (JST)
Subject: [ruby-changes:25524] nobu:r37581 (trunk): array.c: steal shared array's container when ARY_SHARED_NUM == 1

nobu	2012-11-09 16:08:38 +0900 (Fri, 09 Nov 2012)

  New Revision: 37581

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

  Log:
    array.c: steal shared array's container when ARY_SHARED_NUM == 1
    
    * array.c (rb_ary_modify): steal shared array's container when
      ARY_SHARED_NUM == 1.  [Feature #6638]
      - Do not allocate new memory in rb_ary_modify when ARY_SHARED_NUM == 1
        and length almost same.
      - Store ARY_CAPA instead of RARRAY_LEN in ary_make_shared, to make
        it useful.
      - Fix rb_ary_sort_bang accordantly.

  Modified files:
    trunk/ChangeLog
    trunk/array.c

Index: array.c
===================================================================
--- array.c	(revision 37580)
+++ array.c	(revision 37581)
@@ -255,15 +255,24 @@
     rb_ary_modify_check(ary);
     if (ARY_SHARED_P(ary)) {
         long len = RARRAY_LEN(ary);
+	VALUE shared = ARY_SHARED(ary);
         if (len <= RARRAY_EMBED_LEN_MAX) {
             VALUE *ptr = ARY_HEAP_PTR(ary);
-            VALUE shared = ARY_SHARED(ary);
             FL_UNSET_SHARED(ary);
             FL_SET_EMBED(ary);
             MEMCPY(ARY_EMBED_PTR(ary), ptr, VALUE, len);
             rb_ary_decrement_share(shared);
             ARY_SET_EMBED_LEN(ary, len);
         }
+	else if (ARY_SHARED_NUM(shared) == 1 && len > (RARRAY_LEN(shared)>>1)) {
+	    long shift = RARRAY_PTR(ary) - RARRAY_PTR(shared);
+	    ARY_SET_PTR(ary, RARRAY_PTR(shared));
+	    ARY_SET_CAPA(ary, RARRAY_LEN(shared));
+	    MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+shift, VALUE, len);
+	    FL_UNSET_SHARED(ary);
+	    FL_SET_EMBED(shared);
+	    rb_ary_decrement_share(shared);
+	}
         else {
             VALUE *ptr = ALLOC_N(VALUE, len);
             MEMCPY(ptr, RARRAY_PTR(ary), VALUE, len);
@@ -454,8 +463,9 @@
 	NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY);
         FL_UNSET_EMBED(shared);
 
-        ARY_SET_LEN((VALUE)shared, RARRAY_LEN(ary));
+        ARY_SET_LEN((VALUE)shared, ARY_CAPA(ary));
         ARY_SET_PTR((VALUE)shared, RARRAY_PTR(ary));
+	rb_mem_clear(RARRAY_PTR(shared) + RARRAY_LEN(ary), ARY_CAPA(ary) - RARRAY_LEN(ary));
 	FL_SET_SHARED_ROOT(shared);
 	ARY_SET_SHARED_NUM((VALUE)shared, 1);
 	FL_SET_SHARED(ary);
@@ -2188,12 +2198,13 @@
     if (RARRAY_LEN(ary) > 1) {
 	VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
 	struct ary_sort_data data;
+	long len = RARRAY_LEN(ary);
 
 	RBASIC(tmp)->klass = 0;
 	data.ary = tmp;
 	data.opt_methods = 0;
 	data.opt_inited = 0;
-	ruby_qsort(RARRAY_PTR(tmp), RARRAY_LEN(tmp), sizeof(VALUE),
+	ruby_qsort(RARRAY_PTR(tmp), len, sizeof(VALUE),
 		   rb_block_given_p()?sort_1:sort_2, &data);
 
         if (ARY_EMBED_P(tmp)) {
@@ -2210,7 +2221,7 @@
             if (ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
                 assert(!ARY_EMBED_P(ary));
                 FL_UNSET_SHARED(ary);
-                ARY_SET_CAPA(ary, ARY_CAPA(tmp));
+                ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
             }
             else {
                 assert(!ARY_SHARED_P(tmp));
@@ -2225,8 +2236,8 @@
                     xfree(ARY_HEAP_PTR(ary));
                 }
                 ARY_SET_PTR(ary, RARRAY_PTR(tmp));
-                ARY_SET_HEAP_LEN(ary, RARRAY_LEN(tmp));
-                ARY_SET_CAPA(ary, ARY_CAPA(tmp));
+                ARY_SET_HEAP_LEN(ary, len);
+                ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
             }
             /* tmp was lost ownership for the ptr */
             FL_UNSET(tmp, FL_FREEZE);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37580)
+++ ChangeLog	(revision 37581)
@@ -1,3 +1,41 @@
+Fri Nov  9 16:08:35 2012  Sokolov Yura funny-falcon  <funny.falcon@g...>
+
+	* array.c (rb_ary_modify): steal shared array's container when
+	  ARY_SHARED_NUM == 1.  [Feature #6638]
+	  - Do not allocate new memory in rb_ary_modify when ARY_SHARED_NUM == 1
+	    and length almost same.
+	  - Store ARY_CAPA instead of RARRAY_LEN in ary_make_shared, to make
+	    it useful.
+	  - Fix rb_ary_sort_bang accordantly.
+
+	* array.c: speedup Array#unshift by using space in shared array.
+	  [Feature #6638]
+	  - when array owns its shared array (ARY_SHARED_NUM == 1), and there
+	    is enough space then try unshift values directly into shared
+	    array.
+	  - when resulting array is big (~>64 items) then make it shared with
+	    enough room for future #unshifts, and then insert into shared
+	    array.
+
+	* array.c (rb_ary_splice): use shared array in rb_ary_slice.
+	  [Feature #6638]
+	  - use ary_ensure_room_for_push when rb_ary_slice used to add at the
+	    end of array, cause rb_ary_concat use rb_ary_slice.
+
+	* array.c (ary_ensure_room_for_push): make array really suitable for
+	  queue.  [Feature #6638]
+	  when array is shared (which happens after Array#shift), and
+	  ARY_SHARED_NUM == 1 (which is very often when array used as queue),
+	  then make rb_ary_push push directly into shared array.
+
+	* array.c (rb_ary_modify): steal shared array's container when
+	  ARY_SHARED_NUM == 1.  [Feature #6638]
+	  - Do not allocate new memory in rb_ary_modify when ARY_SHARED_NUM == 1
+	    and length almost same.
+	  - Store ARY_CAPA instead of RARRAY_LEN in ary_make_shared, to make
+	    it useful.
+	  - Fix rb_ary_sort_bang accordantly.
+
 Fri Nov  9 16:00:00 2012  Zachary Scott  <zzak@z...>
 
 	* ext/bigdecimal/bigdecimal.c:

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

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