SetBatchLines, -1
arr := []
Loop 100000 {
Random, rand
arr.Push({value: rand})
}
start := A_TickCount
res1 := SortByKey(arr, "value", true)
end1 := A_TickCount
res2 := SortDescending(arr, "value")
end2 := A_TickCount
MsgBox % A_Clipboard := end1 - start . "`n" . end2 - end1 . "`n`n" . PrintArray(res1) . "`n`n" . PrintArray(res2)
SortDescending(arr, key, sort = "R N", del = "|") {
res := [], ex := {}, str := ""
for k, v in arr {
str .= v[key] del
If !ex[v[key]]
ex[v[key]] := []
ex[v[key]].push(k)
}
Sort str, U D%del% Z %sort%
Loop, Parse, str, %del%
{
for k, v in ex[A_LoopField]
res.push(arr[v])
}
Return res
}
SortByKey(arr, key, reverse := false) {
stack := []
stack.Push([1, arr.Length()])
while (stack.Length() > 0) {
low := stack.Pop()
high := low[2]
low := low[1]
while (high - low > 10) {
pivotIndex := MedianOfThree(arr, low, high, key, reverse)
pivotIndex := Partition(arr, low, high, pivotIndex, key, reverse)
if (pivotIndex - low < high - pivotIndex) {
stack.Push([pivotIndex + 1, high])
high := pivotIndex - 1
} else {
stack.Push([low, pivotIndex - 1])
low := pivotIndex + 1
}
}
InsertionSort(arr, low, high, key, reverse)
}
return arr
}
MedianOfThree(arr, low, high, key, reverse) {
mid := low + (high - low) // 2
if reverse {
if (arr[low, key] < arr[mid, key])
Swap(arr, low, mid)
if (arr[mid, key] < arr[high, key])
Swap(arr, mid, high)
if (arr[low, key] < arr[mid, key])
Swap(arr, low, mid)
} else {
if (arr[low, key] > arr[mid, key])
Swap(arr, low, mid)
if (arr[mid, key] > arr[high, key])
Swap(arr, mid, high)
if (arr[low, key] > arr[mid, key])
Swap(arr, low, mid)
}
return mid
}
Partition(arr, low, high, pivotIndex, key, reverse) {
pivot := arr[pivotIndex, key]
Swap(arr, pivotIndex, high)
i := low - 1
Loop, % high - low {
j := A_Index + low - 1
compare := !reverse ? arr[j, key] < pivot : arr[j, key] > pivot
if compare {
i++
Swap(arr, i, j)
}
}
Swap(arr, i + 1, high)
return i + 1
}
InsertionSort(arr, low, high, key, reverse) {
Loop, % high - low {
i := A_Index + low
j := i
while (j > low) {
compare := !reverse ? arr[j, key] < arr[j-1, key] : arr[j, key] > arr[j-1, key]
if compare
Swap(arr, j, j-1)
else
break
j--
}
}
}
Swap(arr, i, j) {
temp := arr[i]
arr[i] := arr[j]
arr[j] := temp
}
PrintArray(arr, del = "") {
for k, v in arr
str .= del k ":" ((IsFunc(v) ? "__Function" : IsObject(v) ? PrintArray(v, del) : (v + 0 != "" ? v : """" v """")))", "
Return "{" RTrim(str, ", ") del "}"
}