Skip to content

Optimize PrimitiveMapper for numeric types#340

Merged
schultek merged 2 commits into
schultek:mainfrom
fabricio-costa:optimize-primitive-mappers
Mar 8, 2026
Merged

Optimize PrimitiveMapper for numeric types#340
schultek merged 2 commits into
schultek:mainfrom
fabricio-costa:optimize-primitive-mappers

Conversation

@fabricio-costa
Copy link
Copy Markdown
Contributor

Summary

  • Optimizes PrimitiveMapper<int>, PrimitiveMapper<double>, and PrimitiveMapper<num> in mapper_container.dart to avoid unnecessary string roundtrips when the input is already a num.
  • When the input is numeric, the mappers now use direct conversion (v.round(), v.toDouble(), identity) instead of num.parse(v.toString()) or double.parse(v.toString()), avoiding an intermediate string allocation.
  • Falls back to string parsing for non-numeric inputs, preserving full backwards compatibility.

Before

PrimitiveMapper<int>((v) => num.parse(v.toString()).round()),
PrimitiveMapper<double>((v) => double.parse(v.toString())),
PrimitiveMapper<num>((v) => num.parse(v.toString()), num),

After

PrimitiveMapper<int>((v) => v is num ? v.round() : num.parse(v.toString()).round()),
PrimitiveMapper<double>((v) => v is num ? v.toDouble() : double.parse(v.toString())),
PrimitiveMapper<num>((v) => v is num ? v : num.parse(v.toString()), num),

Rationale

In typical deserialization from JSON (via dart:convert), numeric values are already int or double. The previous code always went through a string roundtrip (v.toString() then parse), which allocates a temporary string for every numeric field decoded. The optimized version short-circuits this with a type check, which is essentially free in Dart.

Test plan

  • Existing test/primitives/primitives_test.dart passes (covers fromValue<int>('1'), fromValue<double>('1.1'), fromValue<num>(123), and error cases)
  • Existing test/container/container_test.dart passes (covers fromValue<int>('2') and list decoding with mixed types like ['2', 1.5, 0])
  • No other files are modified

f-b-costa and others added 2 commits February 28, 2026 11:48
…g roundtrips

When decoding numeric values (int, double, num), the previous implementation
always converted through a string intermediary (e.g. double.parse(v.toString())).
This is wasteful when the input is already a num. The optimized mappers now
check for num first and use direct conversion (toDouble, round), falling back
to string parsing only for non-numeric inputs.
Copy link
Copy Markdown
Owner

@schultek schultek left a comment

Choose a reason for hiding this comment

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

Thanks, LGTM.

@schultek schultek merged commit a196686 into schultek:main Mar 8, 2026
1 check passed
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.

3 participants