-
Notifications
You must be signed in to change notification settings - Fork 651
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.prototype.sort isn't stable #212
Comments
There is more information of second problem: first sort result:
second sort result:
third sort result:
fourth sort reuslt:
Next time it will go back to first result. |
I think both of these observed effects are due to the same underlying issue (that was touched upon in the last issue you mentioned #95): Our current We have a variety of sorting strategies based on the array:
If you modify your examples to be 6 elements or fewer, you will notice they will produce the results you expect. Your second example shows that an unstable sort can produce different results when called multiple times, since it doesn't guarantee that equal keys stay in the same position. Since tc39 has made a stable The only changes that need to be made are in |
@dulinriley Can I try out this issue? |
@tinfoil-knight Sure thing! Here is some advice to get you started:
|
@tinfoil-knight Were you able to try out a stable sort implementation? Do you need any help? |
@dulinriley No. I tried to read and understand TimSort but I got nowhere. Sorry for not sending out an update. I still have no idea as to how to implement TimSort. I'll update you if I can solve the issue or not. |
@dulinriley Unfortunately, I don't think I've enough clarity on multiple things to make changes to the codebase. I find Timsort to be very complex. I'm freeing this issue up. I'm really sorry. |
If Timsort is too difficult, we can use any stable sort for now (such as merge sort) to fix the immediate bug, and come back to optimize it with a more sophisticated algorithm later. @tinfoil-knight do you want to try with a simpler sorting algorithm instead? |
No. I don't really know how the library is handling multiple things. |
@dulinriley would it be okay if I took a stab at this? |
Hi @nairboh, we just found someone internally who was interested in working on it. |
Glad this is being worked on, @dulinriley any word on the internal progress? |
For those looking for a fix in the meantime, I was able to make use of lodash.sortBy() to get the sorting I needed. |
We have a fix written up, and going through review. It'll auto-close this issue when it hits Github. |
Summary: The implementation of a stable sort in Hermes had a bug in dealing with comparators that modified the array being sorted. Reopens issue #212 Reviewed By: tmikov Differential Revision: D23437337 fbshipit-source-id: b7a0c26ee7e6b171b857561d628c809581b2ed61
This issue has recurred in version 0.7.2. |
@mikunimaru What issue? Without more information, we cannot help. |
Array.prototype.sort is not yet stable sort.
result (enableHermes: false) result (enableHermes: true) Since stable sorting is performed only when Hermes is disabled, there is a risk of causing a bug due to this difference in behavior. Hermes version: 0.7.2 |
Ah, yes, Hermes does not yet fully support ES2019, which is the first version of the spec requiring a stable sort. I will reopen the issue. We don't have immediate plans to work on this (there are higher priority tasks to finish first), but contributions are welcome. |
Hello @tmikov, does anyone has any update about this issue ? I believe it's quiet a major issue, since it prevents us from using the native sort function along with a comparison function as soon as Hermes is enabled, right ? @mikunimaru Did you find any workaround ? Would be glad to help but I'm unsure about what needs to be done exactly to make that function stable, any directions ? Thanks a lot |
@rlemasquerier someone needs to implement the stable sort in Hermes. Unfortunately it is not trivial, for a few reasons:
The first two points mean that the standard C++ library is out. In practice an existing sort routine can't readily be reused, at least not without heavy customization. The easiest solution probably is to find a stable sort implementation in JS and polyfill it. In fact, if it is suitably licensed, we can include it in Hermes. Though, of course, there will be a performance penalty. |
Hey guys! let x = [8, 4, 9, 1, 0, 4, 3, 6];
const s = Array.prototype.sort.call(x, (a, b) => a - b); And this would sort the array |
It does not; s and x are the same exact array instance. |
Hi, Is this issue available? I would like to work on this issue. |
Yes, it is available. |
can I work on it? |
Hey @vicky1999, I'm working on an implementation (working on my machine locally and will fork the repo when I am done and commit the changes there). I'm trying to implement Timsort (bufferless) taking inspiration from |
Hey Guys, Now, I'll try to implement in place merge sort. |
Just curious, timsort is built on top of insertion sort, then why can't we use stable insertion sort? |
Hey! |
Ran into a quite nasty bug in a third party library after enabling Hermes due to this. More details in: kylerjensen/react-native-font-faces#289 Was able to fix it in a PR, via the following JS based stable sorting function: /**
* The Hermes JS engine does not do a stable sort: https://github.com/facebook/hermes/issues/212
*/
export function stableSort<T>(array: T[], ...compareFns: Array<(a: T, b: T) => number>) {
return compareFns.reduce((final, compareFn) => {
return final
.map((item, index) => ({ item, index }))
.sort((a, b) => compareFn(a.item, b.item) || a.index - b.index)
.map(({ item }) => item)
}, array);
} You can see the diff in: https://github.com/kylerjensen/react-native-font-faces/pull/290/files Leaving it here in case it helps someone. |
I don't understand why is this not a P0 for Hermes team to fix? This is a very nasty low level bug. PLease prioritize. Array.sort is very frequently used |
Array.prototype.sort is stable as of commit ec424a1 |
Hermes version: 0.2.1 ~ 0.4.1
I noticed the issues about Infinite loop when sorting , and find two others problem about Array.sort with a comparator.
and get result in hermes:
which we will get in chrome:
The order of the objects has been changed by Array.sort, I am not sure if it is a bug.
first sort result:
second sort reslut:
Every time I tap the button to get a sort result is different.
In our business code,
key
may be the weight of the object. The array will be displayed byListView
, because of the uncertain sort results, the display order will be changed and will confuse the user.Of cause we can fix this by make the comparator more complex, but I don` t think it is a good idea.
BTW, this problem only happen when I define the array in global field, it is fine when I define the array into a function.
The text was updated successfully, but these errors were encountered: