Skip to content

perf : Use GetStringRegion for JavaTurboModule string returns - #58611

Open
riteshshukla04 wants to merge 2 commits into
react:mainfrom
riteshshukla04:fix/java-turbomodule-string-return
Open

riteshshukla04 wants to merge 2 commits into
react:mainfrom
riteshshukla04:fix/java-turbomodule-string-return

Conversation

@riteshshukla04

@riteshshukla04 riteshshukla04 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary:

I changed the sync Java TurboModule string return path to copy the jstring with GetStringRegion into a 256 char stack buffer (heap above that), going from 3 JNI calls (GetStringLength, GetStringChars, ReleaseStringChars) -> 2 (GetStringLength, GetStringRegion) per call.

I did 100_000 calls of SampleTurboModule.getString(s)

Phase Median ms Min Max
Without fix, round 1 86 83 104
With fix, round 1 82 78 87
Without fix, round 2 93 85 124
With fix, round 2 82.5 77 92

For some things like NativeAppearance.getColorScheme() I got upto 19% improvement.

The 256 number is just a POC. We can try 512 or 1024 or something. I am happy to discuss on this .

Changelog:

[ANDROID][CHANGED] - Use GetStringRegion for JavaTurboModule to reduce JNI calls from 3->2

Test Plan:

I ran maestro tests locally . Everything seems to pass.
I also asked claude to create a set of test cases with different string types(text, String , emojis) in turbo module to see nothing breaks

@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 21, 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 21, 2026
@javache

javache commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Cool idea! I wonder if there's higher impact areas for this beyond turbomodule return values (eg WritableNativeMap / WritableNativeArray) - and what the right max stack size to use is.

@javache

javache commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Worth measuring too: the 2nd param to GetStringChars tells you whether a copy was made (and whether this is just pinning memory vs doing an extra copy).

@riteshshukla04

Copy link
Copy Markdown
Contributor Author

Worth measuring too: the 2nd param to GetStringChars tells you whether a copy was made (and whether this is just pinning memory vs doing an extra copy).

I checked the copy thing with the old code, GetStringChars returned isCopy=1 for every string I tried, compressed Latin-1 and uncompressed CJK, different lengths(256,512, 1024,4096). So it always allocates a temporary buffer, copies, and frees it in ReleaseStringChars. With GetStringRegion the copy count stays the same (into my buffer, then into the JSI string) but we have one less JNI call and no malloc/free pair

@riteshshukla04

riteshshukla04 commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

Cool idea! I wonder if there's higher impact areas for this beyond turbomodule return values (eg WritableNativeMap / WritableNativeArray) - and what the right max stack size to use is.

Also I asked claude to create a quick POC accordingly. One more observation here is , we are using val->tostring instead of val->toStdString. So B column is essentially just that. Since we are having JString , using toStdString is worth .

Value A toString() (current) B toStdString() C GetStringRegion + utf16toUTF8 B vs A C vs A
11 ASCII 0.614 0.474 0.431 -23% -30%
100 ASCII 0.800 0.654 0.603 -18% -25%
300 ASCII 1.175 1.022 1.034 -13% -12%
1000 ASCII 2.508 2.320 2.375 -7.5% -5%
100 CJK 1.006 0.863 0.744 -14% -26%

This branch has not been deployed

No deployments
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. 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.

2 participants