mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c: An static assertion for relation of SIZEOF_LONG and
SIZEOF_BDIGITS is added. (bary_mul_precheck): Reduce comparisons. (bary_mul): Invoke bary_sq_fast or bary_mul1 if the bignum size is small. (bigfixize): Resize the argument bignum here. (bignorm): Don't call bigtrunc after bigfixize. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42028 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7c1a2f6192
commit
15f7c7f9d4
2 changed files with 95 additions and 38 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
Wed Jul 17 22:34:47 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c: An static assertion for relation of SIZEOF_LONG and
|
||||||
|
SIZEOF_BDIGITS is added.
|
||||||
|
(bary_mul_precheck): Reduce comparisons.
|
||||||
|
(bary_mul): Invoke bary_sq_fast or bary_mul1 if the bignum size is
|
||||||
|
small.
|
||||||
|
(bigfixize): Resize the argument bignum here.
|
||||||
|
(bignorm): Don't call bigtrunc after bigfixize.
|
||||||
|
|
||||||
Wed Jul 17 22:13:26 2013 Masaki Matsushita <glass.saga@gmail.com>
|
Wed Jul 17 22:13:26 2013 Masaki Matsushita <glass.saga@gmail.com>
|
||||||
|
|
||||||
* hash.c (rb_hash_replace): performance improvement by using
|
* hash.c (rb_hash_replace): performance improvement by using
|
||||||
|
|
95
bignum.c
95
bignum.c
|
@ -47,6 +47,12 @@ STATIC_ASSERT(bdigit_dbl_signedness, 0 < (BDIGIT_DBL)-1);
|
||||||
STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
|
STATIC_ASSERT(bdigit_dbl_signed_signedness, 0 > (BDIGIT_DBL_SIGNED)-1);
|
||||||
STATIC_ASSERT(rbignum_embed_len_max, RBIGNUM_EMBED_LEN_MAX <= (RBIGNUM_EMBED_LEN_MASK >> RBIGNUM_EMBED_LEN_SHIFT));
|
STATIC_ASSERT(rbignum_embed_len_max, RBIGNUM_EMBED_LEN_MAX <= (RBIGNUM_EMBED_LEN_MASK >> RBIGNUM_EMBED_LEN_SHIFT));
|
||||||
|
|
||||||
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_LONG % SIZEOF_BDIGITS == 0);
|
||||||
|
#else
|
||||||
|
STATIC_ASSERT(sizeof_long_and_sizeof_bdigit, SIZEOF_BDIGITS % SIZEOF_LONG == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
# define HOST_BIGENDIAN_P 1
|
# define HOST_BIGENDIAN_P 1
|
||||||
#else
|
#else
|
||||||
|
@ -1911,22 +1917,40 @@ bary_mul_precheck(BDIGIT **zdsp, size_t *zlp, BDIGIT **xdsp, size_t *xlp, BDIGIT
|
||||||
|
|
||||||
assert(xl + yl <= zl);
|
assert(xl + yl <= zl);
|
||||||
|
|
||||||
while (0 < xl && xds[xl-1] == 0)
|
|
||||||
xl--;
|
|
||||||
while (0 < yl && yds[yl-1] == 0)
|
|
||||||
yl--;
|
|
||||||
|
|
||||||
nlsz = 0;
|
nlsz = 0;
|
||||||
while (0 < xl && xds[0] == 0) {
|
|
||||||
|
while (0 < xl) {
|
||||||
|
if (xds[xl-1] == 0) {
|
||||||
|
xl--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do {
|
||||||
|
if (xds[0] != 0)
|
||||||
|
break;
|
||||||
xds++;
|
xds++;
|
||||||
xl--;
|
xl--;
|
||||||
nlsz++;
|
nlsz++;
|
||||||
|
} while (0 < xl);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
while (0 < yl && yds[0] == 0) {
|
}
|
||||||
|
|
||||||
|
while (0 < yl) {
|
||||||
|
if (yds[yl-1] == 0) {
|
||||||
|
yl--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do {
|
||||||
|
if (xds[0] != 0)
|
||||||
|
break;
|
||||||
yds++;
|
yds++;
|
||||||
yl--;
|
yl--;
|
||||||
nlsz++;
|
nlsz++;
|
||||||
|
} while (0 < yl);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nlsz) {
|
if (nlsz) {
|
||||||
MEMZERO(zds, BDIGIT, nlsz);
|
MEMZERO(zds, BDIGIT, nlsz);
|
||||||
zds += nlsz;
|
zds += nlsz;
|
||||||
|
@ -1942,12 +1966,12 @@ bary_mul_precheck(BDIGIT **zdsp, size_t *zlp, BDIGIT **xdsp, size_t *xlp, BDIGIT
|
||||||
}
|
}
|
||||||
assert(xl <= yl);
|
assert(xl <= yl);
|
||||||
|
|
||||||
|
if (xl <= 1) {
|
||||||
if (xl == 0) {
|
if (xl == 0) {
|
||||||
MEMZERO(zds, BDIGIT, zl);
|
MEMZERO(zds, BDIGIT, zl);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xl == 1) {
|
|
||||||
if (xds[0] == 1) {
|
if (xds[0] == 1) {
|
||||||
MEMCPY(zds, yds, BDIGIT, yl);
|
MEMCPY(zds, yds, BDIGIT, yl);
|
||||||
MEMZERO(zds+yl, BDIGIT, zl-yl);
|
MEMZERO(zds+yl, BDIGIT, zl-yl);
|
||||||
|
@ -2059,6 +2083,14 @@ bary_mul_toom3_start(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds
|
||||||
static void
|
static void
|
||||||
bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl)
|
bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds, size_t yl)
|
||||||
{
|
{
|
||||||
|
if (xl < KARATSUBA_MUL_DIGITS) {
|
||||||
|
if (xds == yds && xl == yl)
|
||||||
|
bary_sq_fast(zds, zl, xds, xl);
|
||||||
|
else
|
||||||
|
bary_mul1(zds, zl, xds, xl, yds, yl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bary_mul_toom3_start(zds, zl, xds, xl, yds, yl, NULL, 0);
|
bary_mul_toom3_start(zds, zl, xds, xl, yds, yl, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2275,28 +2307,45 @@ bigtrunc(VALUE x)
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
bigfixize(VALUE x)
|
bigfixize(VALUE x)
|
||||||
{
|
{
|
||||||
long len = RBIGNUM_LEN(x);
|
size_t len = RBIGNUM_LEN(x);
|
||||||
BDIGIT *ds = BDIGITS(x);
|
BDIGIT *ds = BDIGITS(x);
|
||||||
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
|
unsigned long u;
|
||||||
|
#else
|
||||||
|
BDIGIT u;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (0 < len && ds[len-1] == 0)
|
||||||
|
len--;
|
||||||
|
|
||||||
if (len == 0) return INT2FIX(0);
|
if (len == 0) return INT2FIX(0);
|
||||||
if (BIGSIZE(x) <= sizeof(long)) {
|
|
||||||
long num = 0;
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
if (sizeof(long)/SIZEOF_BDIGITS < len)
|
||||||
num = (long)ds[0];
|
goto return_big;
|
||||||
#else
|
else {
|
||||||
while (len--) {
|
int i = (int)len;
|
||||||
num = (long)(BIGUP(num) + ds[len]);
|
u = 0;
|
||||||
|
while (i--) {
|
||||||
|
u = (long)(BIGUP(u) + ds[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#else /* SIZEOF_BDIGITS >= SIZEOF_LONG */
|
||||||
|
if (1 < len || LONG_MAX < ds[0])
|
||||||
|
goto return_big;
|
||||||
|
else
|
||||||
|
u = ds[0];
|
||||||
#endif
|
#endif
|
||||||
if (num >= 0) {
|
|
||||||
if (RBIGNUM_SIGN(x)) {
|
if (RBIGNUM_POSITIVE_P(x)) {
|
||||||
if (POSFIXABLE(num)) return LONG2FIX(num);
|
if (POSFIXABLE(u)) return LONG2FIX((long)u);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (NEGFIXABLE(-num)) return LONG2FIX(-num);
|
if (u <= -FIXNUM_MIN) return LONG2FIX(-(long)u);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return_big:
|
||||||
|
rb_big_resize(x, len);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2305,8 +2354,6 @@ bignorm(VALUE x)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(x, T_BIGNUM)) {
|
if (RB_TYPE_P(x, T_BIGNUM)) {
|
||||||
x = bigfixize(x);
|
x = bigfixize(x);
|
||||||
if (!FIXNUM_P(x))
|
|
||||||
bigtrunc(x);
|
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue