-
Notifications
You must be signed in to change notification settings - Fork 697
Description
Bug Description
- I have run
gradle clean
and confirmed this bug does not occur with JSC
Hermes version: (whatever's in RN 0.70.6)
React Native version (if any): 0.70.6 (the current latest)
OS version (if any): Android 13
Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): arm64-v8a
Steps To Reproduce
- Clone https://github.com/gnprice/hermes-localecompare-repro .
- Run it with
npx react-native run-android
. - Observe the log lines showing calls to
String.prototype.localeCompare
taking multiple seconds each. For example:
LOG sorting...
LOG slow localeCompare: 8836ms for 'vihmdxim' vs 'vlqkdtzn'
LOG slow localeCompare: 2078ms for 'ezkvpvbg' vs 'ivkpfinh'
LOG slow localeCompare: 6568ms for 'ctanfzkj' vs 'ctjhzdyi'
LOG slow localeCompare: 7639ms for 'hgyzpilj' vs 'hhpnlwqf'
LOG slow localeCompare: 7337ms for 'jzninmrt' vs 'orbuzdcq'
LOG slow localeCompare: 6872ms for 'rnarhxnr' vs 'rnauqlwl'
LOG slow localeCompare: 3648ms for 'nfdeptde' vs 'nfgpjekx'
LOG ...done, took 56938ms
Those extremely slow calls are rare relative to the total number of calls. But because they're so extremely slow, they account for most of the total time — about 75% of the whole sort in this example.
code example
The repro repo above just consists of a fresh React Native app on the latest version (from npx react-native init
), with the following code added at the top of the render function:
const randInt = (end, start = 0) =>
Math.floor(Math.random() * (end - start) + start);
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
const names = Array.from({length: 30000}, () =>
Array.from({length: 8}, () => alphabet[randInt(alphabet.length)]).join(''),
);
console.log('sorting...');
const s = Date.now();
names.sort(localeCompare);
console.log(`...done, took ${Date.now() - s}ms`);
function localeCompare(a, b) {
const s = Date.now();
const result = a.localeCompare(b);
const e = Date.now();
if (e - s > 100) {
console.log(`slow localeCompare: ${e - s}ms for '${a}' vs '${b}'`);
}
return result;
}
That is, it makes up a long list of boring short alphabetic strings, and sorts them. The comparator just calls String.prototype.localeCompare
, and times the call.
The Expected Behavior
Calling localeCompare
on a string should be fast — certainly far less than a second, for any non-gigantic strings.
Other notes
I do not reproduce the issue when running in an emulated Android device, on x86_64. So it may be architecture-dependent.