mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-25 14:53:32 +00:00
Optimizing the performance of array.prototype.sort.
Signed-off-by: liujia178 <liujia178@huawei.com>
This commit is contained in:
parent
43d0fa3d5a
commit
4a929ced39
@ -498,10 +498,87 @@ void JSArray::SortElements(JSThread *thread, const JSHandle<TaggedArray> &elemen
|
||||
{
|
||||
ASSERT(fn->IsUndefined() || fn->IsCallable());
|
||||
|
||||
uint32_t len = elements->GetLength();
|
||||
// 64: if the elements is more than 64, use merge-sort algorithm.
|
||||
if (len < 64) {
|
||||
SortElementsByInsertionSort(thread, elements, len, fn);
|
||||
} else {
|
||||
SortElementsByMergeSort(thread, elements, fn, 0, len - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void JSArray::SortElementsByMergeSort(JSThread *thread, const JSHandle<TaggedArray> &elements,
|
||||
const JSHandle<JSTaggedValue> &fn, int64_t startIdx, int64_t endIdx)
|
||||
{
|
||||
if (startIdx >= endIdx)
|
||||
return;
|
||||
|
||||
int64_t middleIdx = startIdx + (endIdx - startIdx) / 2; // 2: half
|
||||
SortElementsByMergeSort(thread, elements, fn, startIdx, middleIdx);
|
||||
SortElementsByMergeSort(thread, elements, fn, middleIdx + 1, endIdx);
|
||||
MergeSortedElements(thread, elements, fn, startIdx, middleIdx, endIdx);
|
||||
}
|
||||
|
||||
void JSArray::MergeSortedElements(JSThread *thread, const JSHandle<TaggedArray> &elements,
|
||||
const JSHandle<JSTaggedValue> &fn, int64_t startIdx,
|
||||
int64_t middleIdx, int64_t endIdx)
|
||||
{
|
||||
int64_t leftLength = middleIdx - startIdx + 1;
|
||||
int64_t rightLength = endIdx - middleIdx;
|
||||
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<TaggedArray> leftArray = factory->NewTaggedArray(leftLength);
|
||||
JSHandle<TaggedArray> rightArray = factory->NewTaggedArray(rightLength);
|
||||
|
||||
for (int64_t i = 0; i < leftLength; i++) {
|
||||
leftArray->Set(thread, i, elements->Get(startIdx + i));
|
||||
}
|
||||
for (int64_t j = 0; j < rightLength; j++) {
|
||||
rightArray->Set(thread, j, elements->Get(middleIdx + 1 + j));
|
||||
}
|
||||
|
||||
int64_t i = 0;
|
||||
int64_t j = 0;
|
||||
int64_t k = startIdx;
|
||||
JSMutableHandle<JSTaggedValue> leftValue(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> rightValue(thread, JSTaggedValue::Undefined());
|
||||
while (i < leftLength && j < rightLength) {
|
||||
leftValue.Update(leftArray->Get(i));
|
||||
rightValue.Update(rightArray->Get(j));
|
||||
int64_t compareRet = base::ArrayHelper::SortCompare(thread, fn, leftValue, rightValue);
|
||||
RETURN_IF_ABRUPT_COMPLETION(thread);
|
||||
if (compareRet <= 0) {
|
||||
elements->Set(thread, k, leftArray->Get(i));
|
||||
i++;
|
||||
} else {
|
||||
elements->Set(thread, k, rightArray->Get(j));
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
while (i < leftLength) {
|
||||
elements->Set(thread, k, leftArray->Get(i));
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
|
||||
while (j < rightLength) {
|
||||
elements->Set(thread, k, rightArray->Get(j));
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
void JSArray::SortElementsByInsertionSort(JSThread *thread, const JSHandle<TaggedArray> &elements, uint32_t len,
|
||||
const JSHandle<JSTaggedValue> &fn)
|
||||
{
|
||||
if (len <= 1)
|
||||
return;
|
||||
|
||||
JSMutableHandle<JSTaggedValue> presentValue(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> middleValue(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> previousValue(thread, JSTaggedValue::Undefined());
|
||||
uint32_t len = elements->GetLength();
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
uint32_t beginIndex = 0;
|
||||
uint32_t endIndex = i;
|
||||
|
@ -112,7 +112,13 @@ public:
|
||||
const JSHandle<JSTaggedValue> &fn);
|
||||
static void SortElementsByObject(JSThread *thread, const JSHandle<JSObject> &thisObjHandle,
|
||||
const JSHandle<JSTaggedValue> &fn);
|
||||
|
||||
static void SortElementsByInsertionSort(JSThread *thread, const JSHandle<TaggedArray> &elements, uint32_t len,
|
||||
const JSHandle<JSTaggedValue> &fn);
|
||||
static void SortElementsByMergeSort(JSThread *thread, const JSHandle<TaggedArray> &elements,
|
||||
const JSHandle<JSTaggedValue> &fn, int64_t startIdx, int64_t endIdx);
|
||||
static void MergeSortedElements(JSThread *thread, const JSHandle<TaggedArray> &elements,
|
||||
const JSHandle<JSTaggedValue> &fn, int64_t startIdx, int64_t middleIdx, int64_t endIdx);
|
||||
|
||||
template <class Callback>
|
||||
static JSTaggedValue ArrayCreateWithInit(JSThread *thread, uint32_t length, const Callback &cb)
|
||||
{
|
||||
|
@ -68,6 +68,23 @@ arr1.sort((a, b) => {
|
||||
});
|
||||
print(JSON.stringify(arr1));
|
||||
|
||||
/*
|
||||
* Test Case Description:
|
||||
* 1. This use case is used to verify the logical processing order of the quick sorting algorithm.
|
||||
* 2. If there are any changes to the use case, please confirm if the use case needs to be modified.
|
||||
*/
|
||||
for (let i = 0; i < 100; i++) {
|
||||
arr1[i] = i;
|
||||
}
|
||||
arr1[0] = 99;
|
||||
arr1[99] = 0;
|
||||
arr1[49] = 50;
|
||||
arr1[50] = 49;
|
||||
arr1.sort((a, b) => {
|
||||
return a - b;
|
||||
})
|
||||
print(JSON.stringify(arr1));
|
||||
|
||||
// Modification of objects during the comparison process.
|
||||
let arr2 = [1, 3, 2];
|
||||
arr2.sort((a, b) => {
|
||||
|
@ -20,6 +20,7 @@ comparing a = 1, b = 3
|
||||
comparing a = 3, b = 2
|
||||
comparing a = 1, b = 2
|
||||
[1,2,3]
|
||||
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99]
|
||||
[1,2,3]
|
||||
[1,2,3]
|
||||
{"0":1,"1":2,"2":3,"a":6,"length":3}
|
||||
|
Loading…
x
Reference in New Issue
Block a user