Skip to content

Avoid allocations in Animated string interpolation - #58691

Closed
shubh73 wants to merge 1 commit into
react:mainfrom
shubh73:perf/animated-interpolation-alloc
Closed

shubh73 wants to merge 1 commit into
react:mainfrom
shubh73:perf/animated-interpolation-alloc

Conversation

@shubh73

@shubh73 shubh73 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

createStringInterpolation (string and color outputRanges) allocated two arrays and a closure on every call: interpolations.map(...), then components.map(...).join(''), or a .map in the rgba branch. This runs every frame for JS-driven animations.

This builds the string with a plain loop and computes r/g/b/a as locals. Output is unchanged: I compared 1,442 results (colors, units, negatives, NaN/-0, all extrapolate modes) from before and after the change, and they match exactly.

Hermes via Fantom, 1M calls per sample.

Time (median of 5 runs)

Output range Before After Change
'0deg' → '360deg' 876 ms 704 ms -20%
'0px 0px 0px' → '-10.5px 20px 4px' 1931 ms 1734 ms -10%
'#FF9500' → 'rgba(50, 150, 250, 0.4)' 1577 ms 1337 ms -15%

Memory (from HermesInternal.getInstrumentedStats(), identical across runs)

Output range Allocated per call GCs per 1M calls
'0deg' → '360deg' 901 B → 590 B (-35%) 221 → 145
'0px 0px 0px' → '-10.5px 20px 4px' 1822 B → 1407 B (-23%) 443 → 342
'#FF9500' → 'rgba(50, 150, 250, 0.4)' 1831 B → 1543 B (-16%) 445 → 375
Time ranges (min–max per run median)
Output range Before After
'0deg' → '360deg' 873–879 ms 697–780 ms
'0px 0px 0px' → '-10.5px 20px 4px' 1924–1951 ms 1701–2577 ms (one noisy run)
'#FF9500' → 'rgba(50, 150, 250, 0.4)' 1572–1590 ms 1309–1343 ms

Node/V8 shows the same direction (-29% / -12.5% / -3.9%).

Changelog:

[GENERAL] [CHANGED] - Avoid per-call allocations in Animated string and color interpolation

Test Plan:

  • yarn fantom packages/react-native/Libraries/Animated/__tests__/Interpolation-itest.js: 35 passed (added cases for multiple numeric components and prefix/suffix)
  • yarn fantom packages/react-native/Libraries/Animated: 302 passed
  • yarn test packages/react-native/Libraries/Animated: 65 passed
  • yarn flow-check, yarn lint, yarn format-check-javascript: clean
  • Benchmark: FANTOM_RUN_BENCHMARKS=1 yarn fantom packages/react-native/Libraries/Animated/__tests__/AnimatedInterpolation-benchmark-itest.js. OSS can't run opt mode, so I ran it with @fantom_native_opt false, @fantom_js_opt true, @fantom_js_bytecode false. Not measured on a device.

🤖 Generated with Claude Code

The string and color branches of `createStringInterpolation` allocated two
arrays and a closure per call (`interpolations.map`, `components.map`,
`join`). Build the string with a plain loop and compute rgba channels as
locals instead. Output is unchanged.

Adds `AnimatedInterpolation-benchmark-itest.js` and test cases for strings
with several numeric components.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 26, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Sep 26, 2026
@meta-codesync

meta-codesync Bot commented Sep 27, 2026

Copy link
Copy Markdown

@fabriziocucci has imported this pull request. If you are a Meta employee, you can view this in D122044561.

@meta-codesync meta-codesync Bot closed this in efc5161 Sep 28, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Sep 28, 2026
@meta-codesync

meta-codesync Bot commented Sep 28, 2026

Copy link
Copy Markdown

@fabriziocucci merged this pull request in efc5161.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant