ruby-changes:30044
From: akr <ko1@a...>
Date: Sun, 21 Jul 2013 21:13:58 +0900 (JST)
Subject: [ruby-changes:30044] akr:r42096 (trunk): * bignum.c (bary_mul): Use simple multiplication if yl is small.
akr 2013-07-21 21:13:47 +0900 (Sun, 21 Jul 2013) New Revision: 42096 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42096 Log: * bignum.c (bary_mul): Use simple multiplication if yl is small. (rb_cstr_to_inum): Invoke bigsq instead of bigmul0. (bigsq): Re-implemented. (bigmul0): Invoke bigsq if two arguments are identical. Modified files: trunk/ChangeLog trunk/bignum.c Index: ChangeLog =================================================================== --- ChangeLog (revision 42095) +++ ChangeLog (revision 42096) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Jul 21 21:08:59 2013 Tanaka Akira <akr@f...> + + * bignum.c (bary_mul): Use simple multiplication if yl is small. + (rb_cstr_to_inum): Invoke bigsq instead of bigmul0. + (bigsq): Re-implemented. + (bigmul0): Invoke bigsq if two arguments are identical. + Sun Jul 21 09:58:19 2013 Tanaka Akira <akr@f...> * bignum.c (bary_mul_toom3): New function based on bigmul1_toom3. Index: bignum.c =================================================================== --- bignum.c (revision 42095) +++ bignum.c (revision 42096) @@ -2496,7 +2496,7 @@ bary_mul_toom3_start(BDIGIT *zds, size_t https://github.com/ruby/ruby/blob/trunk/bignum.c#L2496 static void bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl) { - if (xl < KARATSUBA_MUL_DIGITS) { + if (xl < KARATSUBA_MUL_DIGITS || yl < KARATSUBA_MUL_DIGITS) { if (xds == yds && xl == yl) bary_sq_fast(zds, zl, xds, xl); else @@ -3586,7 +3586,7 @@ rb_cstr_to_inum(const char *str, int bas https://github.com/ruby/ruby/blob/trunk/bignum.c#L3586 MEMCPY(vds+i, uds+i, BDIGIT, num_bdigits-i); } } - powerv = bigtrunc(bigmul0(powerv, powerv)); + powerv = bigtrunc(bigsq(powerv)); tds = vds; vds = uds; uds = tds; @@ -5013,12 +5013,39 @@ rb_big_minus(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5013 static VALUE bigdivrem(VALUE, VALUE, volatile VALUE*, volatile VALUE*); static VALUE +bigsq(VALUE x) +{ + long xn, zn; + VALUE z; + BDIGIT *xds, *zds; + + xn = RBIGNUM_LEN(x); + zn = 2 * xn; + + z = bignew(zn, 1); + + xds = BDIGITS(x); + zds = BDIGITS(z); + + if (xn < KARATSUBA_MUL_DIGITS) + bary_sq_fast(zds, zn, xds, xn); + else + bary_mul(zds, zn, xds, xn, xds, xn); + + RB_GC_GUARD(x); + return z; +} + +static VALUE bigmul0(VALUE x, VALUE y) { long xn, yn, zn; VALUE z; BDIGIT *xds, *yds, *zds; + if (x == y) + return bigsq(x); + xn = RBIGNUM_LEN(x); yn = RBIGNUM_LEN(y); zn = xn + yn; @@ -5590,12 +5617,6 @@ rb_big_fdiv(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5617 return DBL2NUM(dx / dy); } -static VALUE -bigsq(VALUE x) -{ - return bigtrunc(bigmul0(x, x)); -} - /* * call-seq: * big ** exponent -> numeric -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/