From 788fcd314fa091edf459a37027b739e45603ae2e Mon Sep 17 00:00:00 2001 From: SamHerts Date: Fri, 13 Mar 2026 15:51:45 -0400 Subject: [PATCH 1/2] Optimize `multiply` function in `bigint.h` for clarity and performance. Swapping from iterator to indices --- bigint.h | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/bigint.h b/bigint.h index 936be5f..c54aeed 100644 --- a/bigint.h +++ b/bigint.h @@ -581,40 +581,30 @@ namespace BigInt { return multiply(rhs, lhs); } - std::vector result(lhs.vec.size() + rhs.vec.size(), 0); + const size_t l_size = lhs.vec.size(); + const size_t r_size = rhs.vec.size(); + const size_t f_size = l_size + r_size; - for (auto it_lhs = lhs.vec.rbegin(); it_lhs != lhs.vec.rend(); ++it_lhs) { - for (auto it_rhs = rhs.vec.rbegin(); it_rhs != rhs.vec.rend(); ++it_rhs) { - // Calculate the product and the corresponding indices in the result vector - long long mul = (*it_lhs) * (*it_rhs); - auto pos_low_it = result.rbegin() + (std::distance(lhs.vec.rbegin(), it_lhs) + std::distance( - rhs.vec.rbegin(), it_rhs)); - auto pos_high_it = pos_low_it + 1; + std::vector result(f_size, 0); - // Add the product to the result vector - *pos_low_it += mul % MAX_SIZE; - if (pos_high_it != result.rend()) { - *pos_high_it += mul / MAX_SIZE; - } + for (size_t i = 0; i < l_size; i++) { + long long lhs_val = lhs.vec[l_size - 1 - i]; + if (lhs_val == 0) continue; - // Handle carry - if (*pos_low_it >= MAX_SIZE) { - if (pos_high_it != result.rend()) { - *pos_high_it += *pos_low_it / MAX_SIZE; - } - *pos_low_it %= MAX_SIZE; - } - } - } + long long carry = 0; + for (size_t j = 0; j < r_size; j++) { + size_t result_idx = f_size - 1 - (i + j); + const unsigned long long cur = static_cast(result[result_idx]) + + static_cast(lhs_val) * rhs.vec[r_size - 1 - j] + static_cast(carry); - // Handle carries for remaining positions - for (auto r_iter = result.rbegin(); r_iter != result.rend() - 1; ++r_iter) { - if (*r_iter >= MAX_SIZE) { - *(r_iter + 1) += *r_iter / MAX_SIZE; - *r_iter %= MAX_SIZE; + result[result_idx] = static_cast(cur % MAX_SIZE); + carry = static_cast(cur / MAX_SIZE); + } + // Final carry for this pass of the inner loop + if (carry) { + result[f_size - 1 - (i + r_size)] += carry; } } - return trim(result); } From 39f36783baf96020ea1ea1b019b2a6897b92257f Mon Sep 17 00:00:00 2001 From: SamHerts Date: Fri, 13 Mar 2026 15:52:22 -0400 Subject: [PATCH 2/2] Increase `number_count` in performance tests from 2 to 50 --- tests/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test.cpp b/tests/test.cpp index 1b660fc..36f549b 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -74,8 +74,8 @@ static auto measure_execution = [](const int count, const char* label, const siz class Test_BigInt_Performance : public ::testing::Test { protected: - static constexpr size_t number_count = 2; const std::vector sizes = {10, 100, 1000, 10000, 50000}; + static constexpr size_t number_count = 50; volatile int dce_sink = 0; void SetUp() override {