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/