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

ruby-changes:30217

From: glass <ko1@a...>
Date: Wed, 31 Jul 2013 17:47:27 +0900 (JST)
Subject: [ruby-changes:30217] glass:r42269 (trunk): * string.c (rb_str_rindex): performance improvement by using

glass	2013-07-31 17:47:13 +0900 (Wed, 31 Jul 2013)

  New Revision: 42269

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

  Log:
    * string.c (rb_str_rindex): performance improvement by using
      memrchr(3).

  Modified files:
    trunk/ChangeLog
    trunk/configure.in
    trunk/string.c

Index: configure.in
===================================================================
--- configure.in	(revision 42268)
+++ configure.in	(revision 42269)
@@ -1789,6 +1789,7 @@ AC_CHECK_FUNCS(log2) https://github.com/ruby/ruby/blob/trunk/configure.in#L1789
 AC_CHECK_FUNCS(lstat)
 AC_CHECK_FUNCS(mblen)
 AC_CHECK_FUNCS(memalign)
+AC_CHECK_FUNCS(memrchr)
 AC_CHECK_FUNCS(mktime)
 AC_CHECK_FUNCS(pipe2)
 AC_CHECK_FUNCS(poll)
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42268)
+++ ChangeLog	(revision 42269)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Jul 31 17:45:39 2013  Masaki Matsushita  <glass.saga@g...>
+
+	* string.c (rb_str_rindex): performance improvement by using
+	  memrchr(3).
+
 Wed Jul 31 16:43:30 2013  Masaki Matsushita  <glass.saga@g...>
 
 	* string.c (rb_str_rindex): refactoring and avoid to call str_nth() if
Index: string.c
===================================================================
--- string.c	(revision 42268)
+++ string.c	(revision 42269)
@@ -2667,11 +2667,68 @@ rb_str_index_m(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/string.c#L2667
     return LONG2NUM(pos);
 }
 
+#if HAVE_MEMRCHR
+static long
+str_rindex(VALUE str, VALUE sub, const char *s, rb_encoding *enc)
+{
+    char *hit, *adjusted;
+    int c;
+    long slen, searchlen;
+    char *sbeg, *e, *t;
+
+    sbeg = RSTRING_PTR(str);
+    e = RSTRING_END(str);
+    t = RSTRING_PTR(sub);
+    slen = RSTRING_LEN(sub);
+    c = *t & 0xff;
+    searchlen = s - sbeg + 1;
+
+    do {
+	/* printf("\"%s\" \"%s\" %ld %ld %d\n", hit, t, slen, searchlen, memcmp(hit, t, slen)); */
+	hit = memrchr(sbeg, c, searchlen);
+	if (!hit) break;
+	adjusted = rb_enc_left_char_head(sbeg, hit, e, enc);
+	if (hit != adjusted) {
+	    searchlen = adjusted - sbeg;
+	    continue;
+	}
+	if (memcmp(hit, t, slen) == 0)
+	    return rb_str_sublen(str, hit - sbeg);
+	searchlen = adjusted - sbeg;
+    } while (searchlen > 0);
+
+    return -1;
+}
+#else
+static long
+str_rindex(VALUE str, VALUE sub, const char *s, rb_encoding *enc)
+{
+    long slen;
+    char *sbeg, *e, *t;
+
+    sbeg = RSTRING_PTR(str);
+    e = RSTRING_END(str);
+    t = RSTRING_PTR(sub);
+    slen = RSTRING_LEN(sub);
+
+    while (s) {
+	if (memcmp(s, t, slen) == 0) {
+	    return pos;
+	}
+	if (pos == 0) break;
+	pos--;
+	s = rb_enc_prev_char(sbeg, s, e, enc);
+    }
+
+    return -1;
+}
+#endif
+
 static long
 rb_str_rindex(VALUE str, VALUE sub, long pos)
 {
     long len, slen;
-    char *s, *sbeg, *e, *t;
+    char *sbeg, *s;
     rb_encoding *enc;
     int singlebyte;
 
@@ -2687,28 +2744,16 @@ rb_str_rindex(VALUE str, VALUE sub, long https://github.com/ruby/ruby/blob/trunk/string.c#L2744
     if (len == 0) return pos;
 
     sbeg = RSTRING_PTR(str);
-    e = RSTRING_END(str);
-    t = RSTRING_PTR(sub);
-    slen = RSTRING_LEN(sub);
 
     if (pos == 0) {
-	if (memcmp(sbeg, t, slen) == 0)
+	if (memcmp(sbeg, RSTRING_PTR(sub), RSTRING_LEN(sub)) == 0)
 	    return 0;
 	else
 	    return -1;
     }
 
-    s = str_nth(sbeg, e, pos, enc, singlebyte);
-
-    while (s) {
-	if (memcmp(s, t, slen) == 0) {
-	    return pos;
-	}
-	if (pos == 0) break;
-	pos--;
-	s = rb_enc_prev_char(sbeg, s, e, enc);
-    }
-    return -1;
+    s = str_nth(sbeg, RSTRING_END(str), pos, enc, singlebyte);
+    return str_rindex(str, sub, s, enc);
 }
 
 

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

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