Native fast path for $round/$trunc of doubles at precision 0

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.1.0-rc0, 9.0.0-rc2
    • Affects Version/s: None
    • Component/s: Performance
    • None
    • Query Integration
    • Fully Compatible
    • v9.0
    • 200
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      What

      `$round`/`$trunc` on a `double` unconditionally round-trips through `Decimal128` (`double -> Decimal128 -> quantize -> double`) in `evaluateRoundOrTrunc`, regardless of precision.

      Add a native fast path: when the precision is `0` and the value is a finite double, use native floating-point rounding (`std::nearbyint` for `$round`, `std::trunc` for `$trunc`) and skip Decimal128.

      • `$round` uses `nearbyint` (ties-to-even under the default `FE_TONEAREST`, matching `kRoundTiesToEven`); `std::round` would be wrong for ties (half-away-from-zero).
      • Non-integer precision, `Decimal128`, `int`/`long`, and non-finite inputs are unchanged (still go through the Decimal128 path). For integer precision the result is numerically identical to the Decimal128 quantize.

      Why

      Profiling `tsbs-expression-query` (`single_groupby_1_1_1_round`) showed `evaluateRoundOrTrunc` was ~11% of the non-idle CPU, ~80% of which is Decimal128 machinery
      (`Decimal128::quantize`, `{}bid128{_}*`, double<->Decimal128 conversions) for what is a precision-0 round of a double.

            Assignee:
            Mariano Shaar
            Reporter:
            Mariano Shaar
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: