Skip to content

perf(sql): improve double-to-decimal conversion with bulk multiply#6799

Merged
bluestreak01 merged 2 commits intomasterfrom
mt_decimal-improve
Feb 22, 2026
Merged

perf(sql): improve double-to-decimal conversion with bulk multiply#6799
bluestreak01 merged 2 commits intomasterfrom
mt_decimal-improve

Conversation

@mtopolnik
Copy link
Copy Markdown
Contributor

Summary

  • Add ofDigitsAndPower(long digits, int power) to the Decimal interface, replacing the digit-by-digit loop in doubleToDecimal() with a single wide multiply.
  • The old code extracted up to 17 individual digits from the Ryu significand via long division, then performed 17 wide additions (128-bit or 256-bit). The new code multiplies the significand by a single power of 10.
  • The improvement is largest for wider types where each wide addition was most expensive.

Benchmark results

master

Query                                     median      min      max   ns/row
--------------------------------------------------------------------------
double -> DECIMAL(18,2)  [Decimal64]      162      140      199   16.3 ns
double -> DECIMAL(38,10) [Decimal128]     199      190      223   20.0 ns
double -> DECIMAL(76,20) [Decimal256]     272      259      283   27.3 ns
double -> VARCHAR        [append]         159      139      174   15.9 ns


branch

Query                                     median      min      max   ns/row
--------------------------------------------------------------------------
double -> DECIMAL(18,2)  [Decimal64]       90       84       96   9.0 ns
double -> DECIMAL(38,10) [Decimal128]      92       83      100   9.3 ns
double -> DECIMAL(76,20) [Decimal256]      99       93      102   10.0 ns
double -> VARCHAR        [append]         172      163      181   17.2 ns

Decimal64 is 1.8x faster, Decimal128 is 2.2x faster, Decimal256 is 2.8x faster. The three types converge to roughly the same cost since the single multiply dominates and the word-width difference matters less for one operation than for 17. VARCHAR is an unrelated control.

Test plan

  • Run NumbersDoubleToDecimalTest
  • Run CastDoubleToDecimalFunctionFactoryTest
  • Run CastTest

🤖 Generated with Claude Code

mtopolnik and others added 2 commits February 21, 2026 11:36
Add a bulk initialization method that sets a decimal to
digits * 10^power using a single wide multiply. This replaces
the digit-by-digit loop pattern in doubleToDecimal() that
performed up to 17 long divisions for digit extraction and
17 wide additions.

The method handles negative powers by storing the digits
directly with scale = -power, so callers can represent
fractions without a separate setScale() call.

Both doubleToDecimal() overloads in Numbers.java now use
ofDigitsAndPower() instead of the ofZero() + loop +
setScale() pattern.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@mtopolnik mtopolnik added SQL Issues or changes relating to SQL execution Performance Performance improvements labels Feb 21, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 21, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mt_decimal-improve

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 24 / 24 (100.00%)

file detail

path covered line new line coverage
🔵 io/questdb/std/Decimal256.java 9 9 100.00%
🔵 io/questdb/std/Decimal128.java 7 7 100.00%
🔵 io/questdb/std/Decimal64.java 6 6 100.00%
🔵 io/questdb/std/Numbers.java 2 2 100.00%

@bluestreak01 bluestreak01 merged commit 2a00bb4 into master Feb 22, 2026
44 checks passed
@bluestreak01 bluestreak01 deleted the mt_decimal-improve branch February 22, 2026 03:18
maciulis pushed a commit to maciulis/questdb that referenced this pull request Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Performance Performance improvements SQL Issues or changes relating to SQL execution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants