Confusing `ensureNullTerminated` in NSDataBigString
See original GitHub issuePlease provide all the information requested. Issues that do not follow this format are likely to stall.
Description
There is an expensive copy operation for data buffer when loading and parsing JS Bundle in RN. In my case, I have a 4.8
MB JS bundle. The instrument shows it takes 15.81 MB in NSData mutableCopyWithZone
, which happens in ensureNullTerminated
in NSDataBigString.
I followed the backtrace showing in the instrument. Saw that the brief process for RCTBridge loading JS bundle is like this:
Initially, I thought it has to treat data buffer in a contiguous region of memory as a null-terminated byte string (NTBS) . In Objective-C, NSData is an immutable object. In order to add the Null
byte, firstly, it has to copy the original immutable NSData object and construct a mutable object.
But when I deleted these mutable copy and return the data directedly. Seems my app works fine. So does the RNTester
.
So I am confused now:
- Is this code necessary? What is it for?
- If it is necessary, why doesn’t the RN packager add
Null
to the bundle as its last byte to align the behavior of iOS lib? - Does Android have a similar process to copy bundle?
React Native version:
Run react-native info
in your terminal and copy the results here.
react-native: v0.63.3
device: iPhone 5s
OS version: 12.4.8
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.
- open
RNTester
inreact-native
repo.react-native/packages/rn-tester
- find
ensureNullTerminated
and set a breakpoint there - run the
RNTester
Expected Results
Describe what you expected to happen.
- remove this expensive copy operation or show us a way to avoid it, like building a JS bundle and add
Null
previously
Snack, code example, screenshot, or link to a repository:
Issue Analytics
- State:
- Created 3 years ago
- Reactions:6
- Comments:7 (2 by maintainers)
So the impact is
mutable
data to append\0
. The memory cost of the object is related to the js bundle size.To my understanding,
ensuring null
seems make no sense here.It got size of actual content in NSDataBigString before copy and ensuring null terminated
In
evaluateJavaScript
phase, it will convertNSDataBigString
to BigStringBuffer; got its valid size for actual contentthe final
JSStringRef
toJSEvaluateScript
also uses actual sizePlease correct me if i am wrong
Really interesting finding, let me try to surface this to the FB team 👍
(and sorry, I’m just finding out about this now)