Skip to content

perf(grid): read thousands-separated numbers in selection stats without a copy (#1520) - #1657

Merged
ZhuchkaTriplesix merged 1 commit into
devfrom
issue/1520-calc-number-scan
Oct 17, 2026
Merged

ZhuchkaTriplesix merged 1 commit into
devfrom
issue/1520-calc-number-scan

Conversation

@ZhuchkaTriplesix

Copy link
Copy Markdown
Member

Closes #1520.

#1614 made the comma copy conditional; this removes it. Selection stats (Sum / Avg / Min / Max under the grid) parsed every cell with a comma as double.tryParse(cell.replaceAll(',', '')), so a drag over formatted numbers made one string per cell on every update.

Change

  • GridSelectionCalcEngine.parseThousandsSeparated reads the number from the code units:
    • commas are skipped wherever they are, exactly like the copy they replace (so 1,5 is still 15, as before; changing that is a separate question);
    • with up to 15 significant digits and a power of ten up to 22 the value is computed exactly: an integer below 2^53 times or divided by an exactly representable power of ten is a single correctly rounded operation;
    • longer numbers fall back to the copy + double.tryParse.
  • Cells without a comma still go straight to double.tryParse, which needs no copy.
  • trim() already returns the cell itself when there is nothing to trim, so a plain cell allocates no strings.

Checked

A standalone Dart script compared it with double.tryParse(s.replaceAll(',', '')) (results, sign of zero, NaN / infinity treated as non-numbers like the engine does):

  • 300,000 random strings over 0-9 , . - + e E;
  • 200,000 money-shaped values (1,234,567.89);
  • edge cases: 5., .5, 1e22 / 1e23, 19+ digits, 9,007,199,254,740,993, NaN, Infinity.

No difference. Speed on 5,000 comma cells: 172 µs per pass instead of 382 µs, with no allocations.

Tests

grid_selection_calc_format_test.dart compares it with the copy on a fixed list (signs, fractions, exponents, commas in odd places, long numbers, exponent overflow), checks -0, and checks that text with commas is not a number.

Not run with flutter test locally; CI decides.

…ut a copy (#1520)

Selection stats parsed a cell with a comma as
double.tryParse(cell.replaceAll(',', '')), one copy per such cell on
every drag update.

GridSelectionCalcEngine.parseThousandsSeparated reads it from the code
units: commas are skipped wherever they are, as in the copy; up to 15
significant digits and a power of ten up to 22 the value is computed
exactly (an integer below 2^53 times or divided by an exact power of
ten is one correctly rounded operation); longer numbers fall back to
the copy. Cells without a comma still go to double.tryParse, and
trim() returns the cell itself when there is nothing to trim.

Checked against the copy on 500,000 random and money-shaped strings:
no difference. 5,000 comma cells: 172 us instead of 382 us per pass.
@github-actions github-actions Bot added frontend Theme parser epic label: frontend performance Theme parser epic label: performance data-grid Interactive data grid, cell editor, filtering, groupings P3 Low priority / Polish & Enhancements labels Oct 17, 2026
@github-actions github-actions Bot added this to the 0.5.0 milestone Oct 17, 2026
@ZhuchkaTriplesix
ZhuchkaTriplesix merged commit af6392f into dev Oct 17, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

data-grid Interactive data grid, cell editor, filtering, groupings frontend Theme parser epic label: frontend P3 Low priority / Polish & Enhancements performance Theme parser epic label: performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant