mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Optimize scm_integer_mul_zi
* libguile/integers.c (bignum_trim1): (bignum_negate_if): New helpers. (scm_integer_mul_zi): Use the mpn API to avoid temporary allocation.
This commit is contained in:
parent
5481222670
commit
d89f75c535
1 changed files with 25 additions and 5 deletions
|
@ -167,6 +167,14 @@ allocate_bignum (size_t nlimbs)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct scm_bignum *
|
||||||
|
bignum_trim1 (struct scm_bignum *z)
|
||||||
|
{
|
||||||
|
ASSERT (z->u.z.size > 0);
|
||||||
|
z->u.z.size -= (z->limbs[z->u.z.size - 1] == 0);
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
static struct scm_bignum *
|
static struct scm_bignum *
|
||||||
negate_bignum (struct scm_bignum *z)
|
negate_bignum (struct scm_bignum *z)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +182,12 @@ negate_bignum (struct scm_bignum *z)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct scm_bignum *
|
||||||
|
bignum_negate_if (int negate, struct scm_bignum *z)
|
||||||
|
{
|
||||||
|
return negate ? negate_bignum (z) : z;
|
||||||
|
}
|
||||||
|
|
||||||
static struct scm_bignum *
|
static struct scm_bignum *
|
||||||
make_bignum_0 (void)
|
make_bignum_0 (void)
|
||||||
{
|
{
|
||||||
|
@ -2906,12 +2920,18 @@ scm_integer_mul_zi (struct scm_bignum *x, scm_t_inum y)
|
||||||
return scm_from_bignum (x);
|
return scm_from_bignum (x);
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
mpz_t result, zx;
|
size_t xn = bignum_limb_count (x);
|
||||||
mpz_init (result);
|
if (xn == 0)
|
||||||
alias_bignum_to_mpz (x, zx);
|
return SCM_INUM0;
|
||||||
mpz_mul_si (result, zx, y);
|
|
||||||
|
struct scm_bignum *result = allocate_bignum (xn + 1);
|
||||||
|
const mp_limb_t *xd = bignum_limbs (x);
|
||||||
|
mp_limb_t yd[1] = { long_magnitude (y) };
|
||||||
|
int negate = bignum_is_negative (x) != (y < 0);
|
||||||
|
mpn_mul (bignum_limbs (result), xd, xn, yd, 1);
|
||||||
scm_remember_upto_here_1 (x);
|
scm_remember_upto_here_1 (x);
|
||||||
return take_mpz (result);
|
return normalize_bignum
|
||||||
|
(bignum_negate_if (negate, (bignum_trim1 (result))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue