0003-Use-div_var-instead-of-div_var_fast-when-the-divisor.patch
text/x-patch
Filename: 0003-Use-div_var-instead-of-div_var_fast-when-the-divisor.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch 0003
Subject: Use div_var() instead of div_var_fast() when the divisor is small.
| File | + | − |
|---|---|---|
| src/backend/utils/adt/numeric.c | 14 | 4 |
From f578051209ec952873795beabadd40b54dbf182a Mon Sep 17 00:00:00 2001
From: Dean Rasheed <dean.a.rasheed@gmail.com>
Date: Sun, 20 Feb 2022 18:10:25 +0000
Subject: [PATCH 3/3] Use div_var() instead of div_var_fast() when the divisor
is small.
When the divisor contains just one base-NBASE digit, div_var() is much
faster than div_var_fast(), since it contains special fast-path code
for that case, and when the divisor has two digits, div_var() is still
somewhat faster, since div_var_fast() has more overhead intended for
larger inputs. Therefore, use div_var() instead of div_var_fast() in
such cases.
Where we know for sure that the divisor is small, such as the
denominators of Taylor series terms, just call div_var() directly.
Otherwise, have div_var_fast() delegate to div_var() when the
divisor is small. This produces a noticeable speedup of exp(), ln()
and the numeric-big regression test.
---
src/backend/utils/adt/numeric.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 909f4eed74..3c1e310ce2 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -8725,6 +8725,16 @@ div_var_fast(const NumericVar *var1, const NumericVar *var2,
NumericDigit *var1digits = var1->digits;
NumericDigit *var2digits = var2->digits;
+ /*
+ * If the divisor has just one or two base-NBASE digits, it is
+ * significantly faster to just use div_var().
+ */
+ if (var2ndigits <= 2)
+ {
+ div_var(var1, var2, result, rscale, round);
+ return;
+ }
+
/*
* First of all division by zero check; we must not be handed an
* unnormalized divisor.
@@ -9840,7 +9850,7 @@ exp_var(const NumericVar *arg, NumericVar *result, int rscale)
}
local_rscale = x.dscale + ndiv2;
- div_var_fast(&x, &tmp, &x, local_rscale, true);
+ div_var(&x, &tmp, &x, local_rscale, true);
free_var(&tmp);
}
@@ -9871,7 +9881,7 @@ exp_var(const NumericVar *arg, NumericVar *result, int rscale)
mul_var(&x, &x, &elem, local_rscale);
set_var_from_var(&const_two, &ni);
- div_var_fast(&elem, &ni, &elem, local_rscale, true);
+ div_var(&elem, &ni, &elem, local_rscale, true);
while (elem.ndigits != 0)
{
@@ -9879,7 +9889,7 @@ exp_var(const NumericVar *arg, NumericVar *result, int rscale)
mul_var(&elem, &x, &elem, local_rscale);
add_var(&ni, &const_one, &ni);
- div_var_fast(&elem, &ni, &elem, local_rscale, true);
+ div_var(&elem, &ni, &elem, local_rscale, true);
}
/*
@@ -10079,7 +10089,7 @@ ln_var(const NumericVar *arg, NumericVar *result, int rscale)
{
add_var(&ni, &const_two, &ni);
mul_var(&xx, &x, &xx, local_rscale);
- div_var_fast(&xx, &ni, &elem, local_rscale, true);
+ div_var(&xx, &ni, &elem, local_rscale, true);
if (elem.ndigits == 0)
break;
--
2.26.2