【发布时间】:2014-06-10 04:22:15
【问题描述】:
我只是在 golang 中玩弄排序,我在 stackoverflow 上找到了一个 qsort 函数。它的运行速度似乎是 golang 中原生排序功能的两倍。我已经尝试了不同的输入大小并测试它是否有效。
谁能解释为什么会这样?
这是你可以在你的电脑上测试的代码:
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func qsort(a []int) []int {
if len(a) < 2 {
return a
}
left, right := 0, len(a)-1
// Pick a pivot
pivotIndex := rand.Int() % len(a)
// Move the pivot to the right
a[pivotIndex], a[right] = a[right], a[pivotIndex]
// Pile elements smaller than the pivot on the left
for i := range a {
if a[i] < a[right] {
a[i], a[left] = a[left], a[i]
left++
}
}
// Place the pivot after the last smaller element
a[left], a[right] = a[right], a[left]
// Go down the rabbit hole
qsort(a[:left])
qsort(a[left+1:])
return a
}
func main() {
// Create an array with random integers
rand.Seed(30)
size := 1000000
array1 := make([]int, size)
start := time.Now()
for i, _ := range array1 {
array1[i] = rand.Int()
}
fmt.Println("Creating array with ", size, " elements...")
fmt.Println("--- ", time.Since(start), " ---")
// Create a copy of the unsorted array
array2 := make([]int, size)
copy(array2, array1)
// Short using native function
start = time.Now()
sort.Ints(array1)
fmt.Println("Sorting with the native sort...")
fmt.Println("--- ", time.Since(start), " ---")
// Sort using custom qsort
start = time.Now()
qsort(array2)
fmt.Println("Sorting with custom qsort...")
fmt.Println("--- ", time.Since(start), " ---")
}
【问题讨论】:
-
内置是否使用qsort? qsort 可能快一点,但也可能慢得令人难以置信(例如,在对已经排序或几乎已经排序的数组进行排序时(这在实践中很常见)。 qsort 的最坏情况是 O(N^2),但对于许多其他类型来说是 O(N log N)。请参阅 this post 了解 Perl 中的类似实验。
-
你应该在 println 之前计算时间增量,然后打印出来,因为 println 可能会干扰你的时间结果。
-
我现在正在编写一个真正的基准测试来尝试回答。首先让我印象深刻的是
sort使用sort.Interface,因此必须在很多使用内置函数的地方调用方法。