guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 73/85: Optimize scm_integer_mul_zz.


From: Andy Wingo
Subject: [Guile-commits] 73/85: Optimize scm_integer_mul_zz.
Date: Thu, 13 Jan 2022 03:40:25 -0500 (EST)

wingo pushed a commit to branch main
in repository guile.

commit ad6811a12b8a3aab68d0610c799c51515ec7c427
Author: Andy Wingo <wingo@pobox.com>
AuthorDate: Sun Jan 9 16:46:27 2022 +0100

    Optimize scm_integer_mul_zz.
    
    * libguile/integers.c (scm_integer_mul_zz): Optimize to avoid temporary
    allocations.
---
 libguile/integers.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/libguile/integers.c b/libguile/integers.c
index ee2907f30..60c0fd34a 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -2939,13 +2939,25 @@ scm_integer_mul_zi (struct scm_bignum *x, scm_t_inum y)
 SCM
 scm_integer_mul_zz (struct scm_bignum *x, struct scm_bignum *y)
 {
-  mpz_t result, zx, zy;
-  mpz_init (result);
-  alias_bignum_to_mpz (x, zx);
-  alias_bignum_to_mpz (y, zy);
-  mpz_mul (result, zx, zy);
+  size_t xn = bignum_limb_count (x);
+  size_t yn = bignum_limb_count (y);
+  if (xn == 0 || yn == 0)
+    return SCM_INUM0;
+
+  struct scm_bignum *result = allocate_bignum (xn + yn);
+  mp_limb_t *rd = bignum_limbs (result);
+  const mp_limb_t *xd = bignum_limbs (x);
+  const mp_limb_t *yd = bignum_limbs (y);
+  int negate = bignum_is_negative (x) != bignum_is_negative (y);
+  if (xd == yd)
+    mpn_sqr (rd, xd, xn);
+  else if (xn <= yn)
+    mpn_mul (rd, yd, yn, xd, xn);
+  else
+    mpn_mul (rd, xd, xn, yd, yn);
   scm_remember_upto_here_2 (x, y);
-  return take_mpz (result);
+  return normalize_bignum
+    (bignum_negate_if (negate, (bignum_trim1 (result))));
 }
 
 int



reply via email to

[Prev in Thread] Current Thread [Next in Thread]