Skip to content

perf(charts): replace substring allocations in ChartData.parseTime with zero-allocation micro-parsers #1514

Open

Description

@ZhuchkaTriplesix

Summary

In lib/features/results/charts/chart_data.dart (lines 56–76), parseTime(String raw) is called in a loop across up to 100,000 rows in isTimeColumn(rows, column) to detect if an X column contains dates:

final text = raw.trim(); // Allocation 1
if (!_isoTime.hasMatch(text)) return null;
final parsed = DateTime.tryParse(text.replaceFirst(' ', 'T')); // Allocation 2
if (parsed.year != int.parse(text.substring(0, 4)) ||     // Allocation 3
    parsed.month != int.parse(text.substring(5, 7)) ||    // Allocation 4
    parsed.day != int.parse(text.substring(8, 10))) {     // Allocation 5
  return null;
}
if (text.length >= 16 &&
    (parsed.hour != int.parse(text.substring(11, 13)) ||  // Allocation 6
        parsed.minute != int.parse(text.substring(14, 16)))) { // Allocation 7
  return null;
}

On a dataset with 100,000 rows, this generates up to 700,000 short-lived String allocations on the UI thread, causing severe GC pauses (300–800 ms) whenever the Charts tab opens.

Architectural Solution: Zero-Allocation Micro-Parsers

Decompose date validation into fast integer micro-parsers operating directly on character code units via s.codeUnitAt(offset):

  1. static int _parse2Digits(String s, int offset)
    • Direct integer calculation: (s.codeUnitAt(offset) - 0x30) * 10 + (s.codeUnitAt(offset + 1) - 0x30).
  2. static int _parse4Digits(String s, int offset)
    • Direct integer calculation: (s.codeUnitAt(offset) - 0x30) * 1000 + ....
  3. static DateTime? _fastParseIsoDateTime(String s)
    • Validates delimiters (s.codeUnitAt(4) == 0x2D for -, 0x3A for :).
    • Extracts year, month, day, hour, minute as unboxed primitive ints without any substrings.
    • Directly constructs DateTime.utc(...) with validated fields.

Acceptance Criteria

  • ChartData.parseTime performs zero substring() and zero replaceFirst() calls.
  • Date column detection on 100,000 rows completes in under 10 ms (benchmarked).
  • Full parity with existing ISO-8601 parsing tests in test/features/results/charts/chart_data_test.dart.

Activity

  1. added
    frontendTheme parser epic label: frontend
    performanceTheme parser epic label: performance
    data-gridInteractive data grid, cell editor, filtering, groupings
    P2Medium priority / Parity & Refactoring
    on Oct 12, 2026
  2. added this to the 0.5.0 milestone on Oct 12, 2026
  3. added a commit that references this issue on Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priority / Parity & Refactoringdata-gridInteractive data grid, cell editor, filtering, groupingsfrontendTheme parser epic label: frontendperformanceTheme parser epic label: performance

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions