[NO QA] perf: Increase initial Hermes heap size for faster startup and delay Young-Gen GC#76154
Conversation
|
|
530f898 to
97b551e
Compare
|
@chrispader What is your ETA for this one? |
|
@mountiny @Julesssss i'm finishing up this PR right now. |
|
The changes in this PR are finished, right now i'm only running some more android build to get reliable numbers. These build are quite time-consuming, therefore i wasn't able to find time for this earlier. I'm currently testing 4MB, 50MB, 150MB, 300MB initial heap size. I think in general 150mb should be a good value for low-end Android devices, but we can fine-grain this even more. If we want to get this pushed sooner than later, we can also merge this PR right away and we can adjust the initial heap size value after i have more reliable numbers. @mountiny @Julesssss what do you think? |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d708a4f9ef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
patches/react-native/react-native+0.81.4+026+perf-increase-initial-heap-size.patch
Show resolved
Hide resolved
No worries, happy to add a small delay to help get it right first time. What devices models are you testing with out of interest? |
|
Fell free to find the best heap size |
I'm benchmarking mainly on a Samsung Galaxy A14 5G (SM-A146DP). This is our baseline low-end Android device at Margelo, which we use for most performance metrics. I've also tested on other low-end devices, which yield similar results. |
|
@Julesssss @mountiny i'll continue my benchmarks tomorrow, but these are the first reliable numbers that i can provide: 20 iterations each, outliers were ignored
As mentioned, i'll also try 50MB and 100MB. As you can see, there is not such a big diff between 150MB and 300MB initial heap size, therefore i would stick with 150MB or lower, depending on my final results. 300MB should still be easily handled by most low-end Android devices, but there's no need for putting that much pressure on memory right from the startup, if the gains are minimal |
|
Thanks for sharing, happy with your suggestion of 150 👍 |
|
finishing this up right now! |
|
Ok just did some more comprehensive testing on another device, and these are the results. 20 iterations each, major outliers were removed
So looking at this, the 300mb setup didn't even improve but slighly worsen performance compared to the 150mb configuration. Not sure why, but maybe because there are certain thresholds that are reached with 300mb initial heap size. Therefore, i think we should go with the initially proposed 150mb. No further changes need. This PR is ready to merge. @Julesssss @mountiny do you agree? 🙌🏼 |
|
Sounds good to me @chrispader, thanks for investigating further |
mountiny
left a comment
There was a problem hiding this comment.
cc @war-in @WoLewicki FYI for the next 0.83 RN update
|
🚧 @mountiny has triggered a test Expensify/App build. You can view the workflow run here. |
|
@brunovjk Can you please verify the app builds and runs fine for you locally? |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
Sure, first thing on Monday |
Reviewer Checklist
Screenshots/VideosAndroid: HybridApp76154_android_native.mov76154_android_native_slow_device.movAndroid: mWeb Chrome76154_android_web.moviOS: HybridApp76154_ios_native.mov |
brunovjk
left a comment
There was a problem hiding this comment.
It builds and runs well.
mountiny
left a comment
There was a problem hiding this comment.
Thank you! @Julesssss is ooo now so I will move this ahead
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
@chrispader I wonder if we couldn't make it configurable 🤔 you wrote that those patches are unlikely to be accepted upstream but what if we allow for configuring that behaviour? Curious about your opinion too @mountiny |
|
🚀 Deployed to staging by https://github.com/mountiny in version: 9.3.10-0 🚀
|
@war-in yes i think that would be an option. I'll see whether it's worth proposing that, but this sounds reasonable. If i create an upstream PR i'd love anyones support 🙌🏼 |
|
🚀 Deployed to production by https://github.com/roryabraham in version: 9.3.10-6 🚀
|


@mountiny
Explanation of Change
By default, the Hermes JS engine uses an initial heap size of 4MB, which can be used for allocating memory for JS values. Once the heap is fully allocated, Hermes will run garbage collection, which takes time and can slow down other work, which is a problem especially during app startup.
With a small tweak in the creation of the Hermes instance (HermesInstance.cpp) we can increase the initial heap size to a higher value (e.g. 150MB) and delay Young-Gen GC on app start until Old-Gen GC is triggered for the first time. Based on my testing, this saves up around 150-300ms in startup time on low-end Android devices (potentially even more!). The saved startup time heavily depends on the device, the available RAM and memory pressure. The good thing about this change is that it does not introduce any downsides, except for higher RAM usage on startup.
Fixed Issues
$ #76859
PROPOSAL:
Tests
Profile and benchmark Android app start.
Offline tests
None needed.
QA Steps
Make sure the app behaves expectedly the same as before.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native