在go语言中Benchmark基准测试( 在后缀为_test.go的文件中,函数原型为 func BenchmarkXxx(b *testing.B) {}的函数 )可以用来帮助我们发现代码的性能和瓶颈, 其最佳实践 应该是我们最常用的 冒泡排序和快速排序的测试了,废话不说,直接上代码:
冒泡排序和快速排序算法代码 sort_algorithm.go
package sorting
import "math/rand"
// 冒泡排序算法
func BubbleSort(arr []int) {
n := len(arr)
for i := 0; i < n-1; i++ {
for j := 0; j < n-i-1; j++ {
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
}
// 快速排序算法入口
func QuickSort(arr []int) {
quickSort(arr, 0, len(arr)-1)
}
// 快排算法
func quickSort(arr []int, low, high int) {
if low < high {
pivot := partition(arr, low, high)
quickSort(arr, low, pivot-1)
quickSort(arr, pivot+1, high)
}
}
// 快排拆分逻辑
func partition(arr []int, low, high int) int {
pivot := arr[high]
i := low - 1
for j := low; j < high; j++ {
if arr[j] < pivot {
i++
arr[i], arr[j] = arr[j], arr[i]
}
}
arr[i+1], arr[high] = arr[high], arr[i+1]
return i + 1
}
// 生成指定长度的随机数字切片
func makeRandomNumberSlice(n int) []int {
numbers := make([]int, n)
for i := range numbers {
numbers[i] = rand.Intn(n)
}
return numbers
}
const LENGTH = 10_000
冒泡排序和快速排序算法代码基准测试用例 sort_algorithm_test.go
注意:b.N 基准函数必须运行目标代码b.N次。在基准测试执行期间, b.N 会被动态调整来确保基准测试函数能够持续足够长的时间,从而确保时间的可靠性。
package sorting
import "testing"
// 基准测试运行命令: go test -bench=. 这里的.表示运行当前所有的基准测试, 也可以指定函数名
// benchmark基准测试用例
func BenchmarkBubbleSort(b *testing.B) {
for i := 0; i < b.N; i++ {
b.StopTimer() // 停止计时
numbers := makeRandomNumberSlice(LENGTH)
b.StartTimer() // 开始计时
BubbleSort(numbers)
}
}
func BenchmarkQuickSort(b *testing.B) {
for i := 0; i < b.N; i++ {
b.StopTimer() // 停止计时
numbers := makeRandomNumberSlice(LENGTH)
b.StartTimer() // 开始计时
QuickSort(numbers)
}
}
运行结果
上面的结果中, 1-4行表示的是你当前测试用的机器的信息
在第5行的测试结果中第一列的 BenchmarkBubbleSort-16 这里的16表示有16个CPU来执行测试;
第二列的数字32表示循环了32次 这个数字越大越好
第三列的 35757363 ns/op 表示 每次操作的用时 35757363 纳秒 这个数字越小越好
通过上面的基准测试结果,我们可以非常直观的得出结论, 快速排序算法的表现最佳 ,他的时间复杂度为 O(n log n), 而冒泡排序表现较差,时间复杂度为 O(n^2)
参考
testing package - testing - Go Packages
https://dev.tekin.cn/