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

ruby-changes:59550

From: Ary <ko1@a...>
Date: Sun, 29 Dec 2019 13:13:01 +0900 (JST)
Subject: [ruby-changes:59550] e5c441a4a2 (master): Optimize Array#rotate!(n) for n = 1 and n = -1

https://git.ruby-lang.org/ruby.git/commit/?id=e5c441a4a2

From e5c441a4a2885da61df9894ac17b69cb3c5811f2 Mon Sep 17 00:00:00 2001
From: Ary Borenszweig <asterite@g...>
Date: Fri, 29 Nov 2019 17:59:47 -0300
Subject: Optimize Array#rotate!(n) for n = 1 and n = -1

For the most common cases of `rotate!` one place to the right or to the
left, instead of doing some reversals of the array we just keep a single
value in a temporary value, use memmove and then put the temporary
value where it should be.

diff --git a/array.c b/array.c
index 9846320..16321e1 100644
--- a/array.c
+++ b/array.c
@@ -2618,10 +2618,20 @@ rotate_count(long cnt, long len) https://github.com/ruby/ruby/blob/trunk/array.c#L2618
 static void
 ary_rotate_ptr(VALUE *ptr, long len, long cnt)
 {
-    --len;
-    if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
-    if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
-    if (len > 0) ary_reverse(ptr, ptr + len);
+    if (cnt == 1) {
+        VALUE tmp = *ptr;
+        memmove(ptr, ptr + 1, sizeof(VALUE)*(len - 1));
+        *(ptr + len - 1) = tmp;
+    } else if (cnt == len - 1) {
+        VALUE tmp = *(ptr + len - 1);
+        memmove(ptr + 1, ptr, sizeof(VALUE)*(len - 1));
+        *ptr = tmp;
+    } else {
+        --len;
+        if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
+        if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
+        if (len > 0) ary_reverse(ptr, ptr + len);
+    }
 }
 
 VALUE
@@ -2631,7 +2641,7 @@ rb_ary_rotate(VALUE ary, long cnt) https://github.com/ruby/ruby/blob/trunk/array.c#L2641
 
     if (cnt != 0) {
         long len = RARRAY_LEN(ary);
-        if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
+        if (len > 1 && (cnt = rotate_count(cnt, len)) > 0) {
             RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
             return ary;
         }
-- 
cgit v0.10.2


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

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