本代码全网首发,使用Go plan9 windows arm64汇编,实现基础版快速排序算法。
未引入随机因子的快速排序的普通Go代码长这样。
func QuickSort(arr []int) {
if len(arr) <= 1 {
return
}
base, l, r := arr[0], 0, len(arr)-1
for i := 1; i <= r; {
if arr[i] > base {
arr[i], arr[r] = arr[r], arr[i]
r--
continue
}
arr[i], arr[l] = arr[l], arr[i]
l, i = l+1, i+1
}
QuickSort(arr[:l])
QuickSort(arr[l+1:])
}
如下,使用windows arm64 Go plan9汇编实现的快速排序。
file: quickSort.s
#include "textflag.h"
// func QuickSortByASM(slice []int)
TEXT ·QuickSortByASM(SB), $104-24
// NO_LOCAL_POINTERS
MOVD R0 , tmp-8*3(SP); MOVD R1 , tmp-8*4(SP)
MOVD R2 , tmp-8*5(SP); MOVD R3 , tmp-8*6(SP)
MOVD R4 , tmp-8*7(SP); MOVD R5 , tmp-8*8(SP)
MOVD R6 , tmp-8*9(SP); MOVD R7 , tmp-8*10(SP)
MOVD R8 , tmp-8*11(SP); MOVD R9 , tmp-8*12(SP)
MOVD R10, tmp-8*13(SP)
MOVD slice+0(FP), R0 // arrayPtr
MOVD slice+8(FP), R1 // arrayLength
MOVD $0, R2 // l_index
MOVD R1, R3 // r_index = arrayLength
SUB $1, R3 // r_index -= 1
MOVD $0, R4 // pointer1
MOVD $0, R5 // pointer2
MOVD $8, R6 // dataSize
MOVD $1, R7 // index
MOVD (R0), R8 // base TODO random index
MOVD $0, R9
CMP $1, R1; BLE LABEL_END // if arrayLength <= 1 return
LABEL_FOR_START:
CMP R3, R7; BGT LABEL_FOR_END // if index > r_index return
MOVD R7, R4 // offset = index
MUL R6, R4 // offset *= dataSize
ADD R0, R4 // arr[i] = R4
MOVD (R4), R5 // arr[i]
CMP R8, R5; BLE LABEL_SWAP // if arr[i] <= base
MOVD R3, R5 // offset = r_index
MUL R6, R5 // offset *= dataSize
ADD R0, R5 // arr[r]
MOVD (R5), R9 // tmp = arr[r]
MOVD (R4), R10 // tmp1 = arr[i]
MOVD R10, (R5) // arr[r] = arr[i]
MOVD R9, (R4) // arr[i] = tmp
SUB $1, R3 // r_index -= 1
JMP LABEL_FOR_START
LABEL_SWAP:
MOVD R7, R4
MUL R6, R4
ADD R0, R4
MOVD R2, R5
MUL R6, R5
ADD R0, R5
MOVD (R4), R9 // tmp = arr[i]
MOVD (R5), R10 // tmp1 = arr[l]
MOVD R10, (R4) // arr[i] = tmp1
MOVD R9, (R5) // arr[l] = tmp
ADD $1, R2 // l_index += 1
ADD $1, R7 // index += 1
JMP LABEL_FOR_START
LABEL_FOR_END:
MOVD R0, R4
MOVD R2, R5
MOVD R4, tmp-104(SP)
MOVD R5, tmp-96(SP)
CALL ·QuickSortByASM(SB)
MOVD R2, R4
ADD $1, R4
MUL R6, R4
ADD R0, R4 // right address
MOVD R1, R5 // tmp = arrayLength
SUB R2, R5 // tmp -= l_index
SUB $1, R5
MOVD R4, tmp-104(SP)
MOVD R5, tmp-96(SP)
CALL ·QuickSortByASM(SB)
LABEL_END:
MOVD tmp-8*3(SP), R0; MOVD tmp-8*4(SP), R1
MOVD tmp-8*5(SP), R2; MOVD tmp-8*6(SP), R3
MOVD tmp-8*7(SP), R4; MOVD tmp-8*8(SP), R5
MOVD tmp-8*9(SP), R6; MOVD tmp-8*10(SP), R7
MOVD tmp-8*11(SP), R8;MOVD tmp-8*12(SP), R9
MOVD tmp-8*13(SP), R10
RET
该汇编版本快排基于普通版快排手写而成, 未加入stackmap信息,大数据量样本可能会出现panic,仅供参考。
对数器
package main
import (
"fmt"
"math/rand"
"sort"
)
func QuickSortByASM(slice []int) // 汇编函数声明
func main() {
N := 50
for index := 0; index < 1000; index++ {
slice := make([]int, N)
for i := 0; i < N; i++ {
slice[i] = rand.Int()
}
slice1 := make([]int, N)
slice2 := make([]int, N)
for i, v := range slice {
slice1[i] = v
slice2[i] = v
}
sort.Ints(slice1)
QuickSortByASM(slice2)
for i := 0; i < N; i++ {
if slice1[i] != slice2[i] {
fmt.Println(slice)
fmt.Println(slice1)
fmt.Println(slice2)
panic(i)
}
}
}
fmt.Println("pass")
}
pass
文章出处登录后可见!
已经登录?立即刷新