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

ruby-changes:15098

From: akr <ko1@a...>
Date: Fri, 19 Mar 2010 05:35:41 +0900 (JST)
Subject: [ruby-changes:15098] Ruby:r26975 (trunk): * string.c (rb_str_sum): don't call method for each byte.

akr	2010-03-19 05:35:18 +0900 (Fri, 19 Mar 2010)

  New Revision: 26975

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

  Log:
    * string.c (rb_str_sum): don't call method for each byte.

  Modified files:
    trunk/ChangeLog
    trunk/string.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26974)
+++ ChangeLog	(revision 26975)
@@ -1,3 +1,7 @@
+Fri Mar 19 05:26:31 2010  Tanaka Akira  <akr@f...>
+
+	* string.c (rb_str_sum): don't call method for each byte.
+
 Thu Mar 18 21:24:21 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* Makefile.in (miniruby): link $(NORMALMAINOBJ).
Index: string.c
===================================================================
--- string.c	(revision 26974)
+++ string.c	(revision 26975)
@@ -6537,7 +6537,7 @@
  *  Returns a basic <em>n</em>-bit checksum of the characters in <i>str</i>,
  *  where <em>n</em> is the optional <code>Fixnum</code> parameter, defaulting
  *  to 16. The result is simply the sum of the binary value of each character in
- *  <i>str</i> modulo <code>2n - 1</code>. This is not a particularly good
+ *  <i>str</i> modulo <code>2**n - 1</code>. This is not a particularly good
  *  checksum.
  */
 
@@ -6548,6 +6548,8 @@
     int bits;
     char *ptr, *p, *pend;
     long len;
+    VALUE sum = INT2FIX(0);
+    unsigned long sum0 = 0;
 
     if (argc == 0) {
 	bits = 16;
@@ -6559,36 +6561,42 @@
     ptr = p = RSTRING_PTR(str);
     len = RSTRING_LEN(str);
     pend = p + len;
-    if (bits >= (int)sizeof(long)*CHAR_BIT) {
-	VALUE sum = INT2FIX(0);
 
-	while (p < pend) {
-	    str_mod_check(str, ptr, len);
-	    sum = rb_funcall(sum, '+', 1, INT2FIX((unsigned char)*p));
-	    p++;
-	}
-	if (bits != 0) {
-	    VALUE mod;
+    while (p < pend) {
+        if (FIXNUM_MAX - 255 < sum0) {
+            sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
+            str_mod_check(str, ptr, len);
+            sum0 = 0;
+        }
+        sum0 += (unsigned char)*p;
+        p++;
+    }
 
-	    mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits));
-	    mod = rb_funcall(mod, '-', 1, INT2FIX(1));
-	    sum = rb_funcall(sum, '&', 1, mod);
-	}
-	return sum;
+    if (bits == 0) {
+        if (sum0) {
+            sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
+        }
     }
     else {
-       unsigned long sum = 0;
+        if (sum == INT2FIX(0)) {
+            if (bits < (int)sizeof(long)*CHAR_BIT) {
+                sum0 &= (((unsigned long)1)<<bits)-1;
+            }
+            sum = LONG2FIX(sum0);
+        }
+        else {
+            VALUE mod;
 
-	while (p < pend) {
-	    str_mod_check(str, ptr, len);
-	    sum += (unsigned char)*p;
-	    p++;
-	}
-	if (bits != 0) {
-           sum &= (((unsigned long)1)<<bits)-1;
-	}
-	return rb_int2inum(sum);
+            if (sum0) {
+                sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
+            }
+
+            mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits));
+            mod = rb_funcall(mod, '-', 1, INT2FIX(1));
+            sum = rb_funcall(sum, '&', 1, mod);
+        }
     }
+    return sum;
 }
 
 static VALUE

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

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