用Go汇编实现一个快速排序算法

news/2024/7/5 2:37:55

本代码全网首发,使用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


http://lihuaxi.xjx100.cn/news/1889732.html

相关文章

【Axure RP9】元件应用(图文并茂)----含登入,个人简历案例

目录 : 一&#xff0c;元件基本介绍 1.1 元件概述 1.2 元件操作 1.3 快捷键大全 二&#xff0c;基本元件的应用 2.1 形状 2.2 图片 2.3 文本 2.4 线段原件 2.5 热区 2.5.1 热区应用 三, 表单型元件的应用 3.1 文本框 3.2 文本域 3.3 下拉列表 3.4 列表框 3.5 …

记录 | vscode禁止插件自动更新的方法

shift command p 打开然后输入 > setting.json&#xff0c;选择用户设置 在 settings.json 配置文件中增加一项&#xff1a; "extensions.autoUpdate": false,

Java数字化健康卫生智慧云HIS系统源码

基于云计算技术的B/S架构云HIS集挂号、处方、收费、取药、病历于一体,完全适配各类中小型医院、诊所。 一、云 HIS定义 1、云 HIS 系统是运用云计算、大数据、物联网等新兴信息技术&#xff0c;按照现代医疗卫生管理要求&#xff0c;在一定区域范围内以数字化形式提供医疗卫生…

【lesson13】MySQL表的基本操作之create(创建),update(更新)和replace(替换)

文章目录 表的增删查改create测试建表基础测试 update测试建表基础测试 replace&#xff08;替换&#xff09;测试建表基础测试 表的增删查改 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; create 测试 建表…

富唯智能自动转运机器人——生产制造业的未来

富唯智能自动转运机器人&#xff0c;一款创新的自动化设备&#xff0c;以其独特的优势&#xff0c;为生产制造业带来了更高效的降本增效解决方案。我们坚信&#xff0c;随着科技的进步&#xff0c;富唯智能自动转运机器人将成为生产制造业的未来。 首先&#xff0c;富唯智能自动…

Excel: Python 如何干掉 VBA 系列 丙

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/FgoU8CxofwY90f3IX2Tpww 获取网络动态数据 本文开始之前夸过海口&#xff0c;说要演示一下喂养家畜的饲料动态成本&#xff0c;其实由于行业数据…

微服务--07--Sentienl中使用的限流算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Sentienl中使用的限流算法1、计数器固定窗口算法2、计数器滑动窗口算法----&#xff08;默认&#xff09;3、漏桶算法----&#xff08;排队等待&#xff09;4、令牌…

***Cpolar配置外网访问和Dashy

Dashy是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航页。一款功能超强大,颜值爆表的可定制专属导航页工具 结合cpolar内网工具,我们实现无需部署到公网服务器…