Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array.protoype.indexOf() Performance Regression #1270

Open
1 of 2 tasks
tctacm opened this issue Jan 23, 2024 · 3 comments
Open
1 of 2 tasks

Array.protoype.indexOf() Performance Regression #1270

tctacm opened this issue Jan 23, 2024 · 3 comments

Comments

@tctacm
Copy link

tctacm commented Jan 23, 2024

Bug Description

The Array.prototype.indexOf() functions seems to be significantly slower on Hermes when compared to JSC. I first noticed the issue in React Native 0.64 inside the JSTimers file: https://github.com/facebook/react-native/blob/0645c38014e8310d8e387dabc860c8c5878beb6e/Libraries/Core/Timers/JSTimers.js#L62 , however, I have reproduced a case using the Hermes CLI to verify my findings.

  • I have run gradle clean and confirmed this bug does not occur with JSC
  • The issue is reproducible with the latest version of React Native.

Hermes git revision (if applicable): release-v0.12? I'm using Hermes CLI with version 0.12.0
React Native version: N/A
OS: macOS Sonoma 14.2.1
Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): x86_64

Steps To Reproduce

The following code running on Hermes will take significantly longer:

index_of_test.js:

const ARR_SIZE = 10000;

// Make an array of ARR_SIZE increasing non-negative integers
// [0, 1, 2, 3, 4, 5, 6, 7, 8, ...]
var test_arr = [];
for (var i = 0; i < ARR_SIZE; i++) {
  test_arr.push(i);
}

// Call indexOf 1000 times with the last element in the array
var start = Date.now();
for (var i = 0; i < 1000; i++) {
  test_arr.indexOf(ARR_SIZE - 1);
}
var end = Date.now();
print('Array.indexOf last element time: ' + (end - start));

// Call indexOf 1000 times with the first element in the array
var start = Date.now();
for (var i = 0; i < 1000; i++) {
  test_arr.indexOf(0);
}
var end = Date.now();
print('Array.indexOf first element time: ' + (end - start));
  1. Run with hermes cli: hermes ./index_of_test.js
Array.indexOf last element time: 253
Array.indexOf first element time: 0
  1. Run with JSC cli: jsc --useJIT=false ./index_of_test.js
Array.indexOf last element time: 3
Array.indexOf first element time: 0

My example seems to indicate that Hermes is much slower at iterating through and comparing Array values when compared to JSC.

Funnily enough, the same test using Array.prototype.includes() has similar performance between Hermes and JSC. I would assume (probably incorrectly) that the two functions use a similar algorithm. Although in this case, JSC is also much slower compared to its indexOf performance.

  1. Run with hermes ~/includes_test.js
Array.includes last element time: 122
Array.includes first element time: 0
  1. Run with jsc --useJIT=false ~/includes_test.js
Array.includes last element time: 116
Array.includes first element time: 0

The Expected Behavior

Hermes performance on Array.protoype.indexOf() should be on-par with JSC performance.

@tctacm tctacm added the bug Something isn't working label Jan 23, 2024
@tmikov
Copy link
Contributor

tmikov commented Jan 24, 2024

Thank you for reporting this! We can reproduce it and will address it. This is most likely because Array.protoype.indexOf() doesn't have a fast-path checking for an array.

@gituser8796
Copy link

Hi @tmikov , is there a target release for this one?

@tmikov
Copy link
Contributor

tmikov commented Feb 29, 2024

React Native releases are not synchronized with Hermes is is hard to predict where anything would land. In any case, this task is open, but we haven't started working on it yet.

@tmikov tmikov added performance and removed bug Something isn't working labels Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants