Skip to content

Optimize Decimal::ToIntegerString by replacing stringstream#581

Open
wgtmac wants to merge 2 commits intoapache:mainfrom
wgtmac:optimize-decimal-string-formatting-4049724441882146694
Open

Optimize Decimal::ToIntegerString by replacing stringstream#581
wgtmac wants to merge 2 commits intoapache:mainfrom
wgtmac:optimize-decimal-string-formatting-4049724441882146694

Conversation

@wgtmac
Copy link
Member

@wgtmac wgtmac commented Feb 27, 2026

Replaced std::ostringstream with a manual stack-allocated buffer and std::to_chars in Decimal::ToIntegerString. This eliminates heap allocations and formatting overhead in a common code path.

Measured improvement: ~3.3x speedup (70% reduction in time) in a focused benchmark.
Correctness verified with boundary and round-trip tests.


PR created automatically by Jules for task 4049724441882146694 started by @wgtmac

Replaced std::ostringstream with a manual stack-allocated buffer and
std::to_chars to reduce allocation and formatting overhead.

Measured a ~3.3x speedup in a standalone benchmark.
Correctness verified with focused tests covering boundary cases and
round-trip conversions.

Co-authored-by: wgtmac <4684607+wgtmac@users.noreply.github.com>
Comment on lines 413 to 414
char buf[48];
char* curr = buf;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
char buf[48];
char* curr = buf;
std::array<char, 48> buf;
char* curr = buf.begin();

I suggest to use std::array instead.

Comment on lines 425 to 432
for (size_t i = num_segments - 1; i-- > 0;) {
oss << std::setw(9) << std::setfill('0') << segments[i];
uint32_t val = segments[i];
for (int j = 8; j >= 0; --j) {
curr[j] = static_cast<char>(val % 10 + '0');
val /= 10;
}
curr += 9;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  for (auto val : segments | std::views::take(num_segments - 1) | std::views::reverse) {
    for (int j = 8; j >= 0; --j) {
      curr[j] = static_cast<char>(val % 10 + '0');
      val /= 10;
    }
    curr += 9;
  }

Use <ranges> for better readability.

- Optimized Decimal::ToIntegerString by replacing std::ostringstream
  with a manual stack-allocated buffer and std::to_chars.
- Fixed CI failure by adding multiple fallback URLs for nanoarrow 0.7.0,
  as the original Apache mirror URL was returning 404.
- Added missing <charconv> and <ostream> headers.
- Added ICEBERG_DCHECK to verify std::to_chars success.

Co-authored-by: wgtmac <4684607+wgtmac@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants