From 788790f0a2e9db16fe9722703382406c3d0ade59 Mon Sep 17 00:00:00 2001 From: tompng Date: Thu, 17 Jul 2025 22:10:54 +0900 Subject: [PATCH 1/2] Remove vpdivd optimization which is not frequetly used It only speeds up about 3% in the best case. About 99.98% case running the test, it won't enter to this optimization path. --- ext/bigdecimal/bigdecimal.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index c7546a7d..7573de40 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -6014,7 +6014,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) size_t i, n, ind_a, ind_b, ind_c, ind_r; size_t nLoop; DECDIG_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2; - DECDIG borrow, borrow1, borrow2; + DECDIG borrow1, borrow2; DECDIG_DBL qb; VpSetNaN(r); @@ -6078,26 +6078,11 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) } /* The first few word digits of r and b is the same and */ /* the first different word digit of w is greater than that */ - /* of b, so quotient is 1 and just subtract b from r. */ - borrow = 0; /* quotient=1, then just r-b */ - ind_b = b->Prec - 1; - ind_r = ind_c + ind_b; - if (ind_r >= word_r) goto space_error; - n = ind_b; - for (i = 0; i <= n; ++i) { - if (r->frac[ind_r] < b->frac[ind_b] + borrow) { - r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow)); - borrow = 1; - } - else { - r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow; - borrow = 0; - } - --ind_r; - --ind_b; - } + /* of b, so quotient is 1. */ + q = 1; ++c->frac[ind_c]; - goto carry; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; } /* The first two word digits is not the same, */ /* then compare magnitude, and divide actually. */ @@ -6150,7 +6135,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) } r->frac[ind_r] -= borrow2; -carry: + /* carry */ ind_r = ind_c; while (c->frac[ind_r] >= BASE) { c->frac[ind_r] -= BASE; From c2deb1cebf895be6802bc519cf4a95d6e94cae5c Mon Sep 17 00:00:00 2001 From: tompng Date: Thu, 17 Jul 2025 22:22:17 +0900 Subject: [PATCH 2/2] Remove unused carry logic in vpdivd --- ext/bigdecimal/bigdecimal.c | 7 ------- test/bigdecimal/test_vp_operation.rb | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 7573de40..76b9a62f 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -6135,13 +6135,6 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) } r->frac[ind_r] -= borrow2; - /* carry */ - ind_r = ind_c; - while (c->frac[ind_r] >= BASE) { - c->frac[ind_r] -= BASE; - --ind_r; - ++c->frac[ind_r]; - } } /* End of operation, now final arrangement */ out_side: diff --git a/test/bigdecimal/test_vp_operation.rb b/test/bigdecimal/test_vp_operation.rb index 1ce3a034..075df0b6 100644 --- a/test/bigdecimal/test_vp_operation.rb +++ b/test/bigdecimal/test_vp_operation.rb @@ -84,7 +84,7 @@ def test_vpdivd_precisions end end - def test_vpdivd_carry_borrow + def test_vpdivd_borrow y_small = BASE / 7 * BASE ** 4 y_large = (4 * BASE_FIG).times.map {|i| i % 9 + 1 }.join.to_i [y_large, y_small].each do |y|