summaryrefslogtreecommitdiff
path: root/src/pkg/sort/sort_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/sort/sort_test.go')
-rw-r--r--src/pkg/sort/sort_test.go553
1 files changed, 0 insertions, 553 deletions
diff --git a/src/pkg/sort/sort_test.go b/src/pkg/sort/sort_test.go
deleted file mode 100644
index 6c36f30e0..000000000
--- a/src/pkg/sort/sort_test.go
+++ /dev/null
@@ -1,553 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sort_test
-
-import (
- "fmt"
- "math"
- "math/rand"
- . "sort"
- "strconv"
- "testing"
-)
-
-var ints = [...]int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
-var float64s = [...]float64{74.3, 59.0, math.Inf(1), 238.2, -784.0, 2.3, math.NaN(), math.NaN(), math.Inf(-1), 9845.768, -959.7485, 905, 7.8, 7.8}
-var strings = [...]string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
-
-func TestSortIntSlice(t *testing.T) {
- data := ints
- a := IntSlice(data[0:])
- Sort(a)
- if !IsSorted(a) {
- t.Errorf("sorted %v", ints)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestSortFloat64Slice(t *testing.T) {
- data := float64s
- a := Float64Slice(data[0:])
- Sort(a)
- if !IsSorted(a) {
- t.Errorf("sorted %v", float64s)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestSortStringSlice(t *testing.T) {
- data := strings
- a := StringSlice(data[0:])
- Sort(a)
- if !IsSorted(a) {
- t.Errorf("sorted %v", strings)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestInts(t *testing.T) {
- data := ints
- Ints(data[0:])
- if !IntsAreSorted(data[0:]) {
- t.Errorf("sorted %v", ints)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestFloat64s(t *testing.T) {
- data := float64s
- Float64s(data[0:])
- if !Float64sAreSorted(data[0:]) {
- t.Errorf("sorted %v", float64s)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestStrings(t *testing.T) {
- data := strings
- Strings(data[0:])
- if !StringsAreSorted(data[0:]) {
- t.Errorf("sorted %v", strings)
- t.Errorf(" got %v", data)
- }
-}
-
-func TestSortLarge_Random(t *testing.T) {
- n := 1000000
- if testing.Short() {
- n /= 100
- }
- data := make([]int, n)
- for i := 0; i < len(data); i++ {
- data[i] = rand.Intn(100)
- }
- if IntsAreSorted(data) {
- t.Fatalf("terrible rand.rand")
- }
- Ints(data)
- if !IntsAreSorted(data) {
- t.Errorf("sort didn't sort - 1M ints")
- }
-}
-
-func TestReverseSortIntSlice(t *testing.T) {
- data := ints
- data1 := ints
- a := IntSlice(data[0:])
- Sort(a)
- r := IntSlice(data1[0:])
- Sort(Reverse(r))
- for i := 0; i < len(data); i++ {
- if a[i] != r[len(data)-1-i] {
- t.Errorf("reverse sort didn't sort")
- }
- if i > len(data)/2 {
- break
- }
- }
-}
-
-func BenchmarkSortString1K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]string, 1<<10)
- for i := 0; i < len(data); i++ {
- data[i] = strconv.Itoa(i ^ 0x2cc)
- }
- b.StartTimer()
- Strings(data)
- b.StopTimer()
- }
-}
-
-func BenchmarkStableString1K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]string, 1<<10)
- for i := 0; i < len(data); i++ {
- data[i] = strconv.Itoa(i ^ 0x2cc)
- }
- b.StartTimer()
- Stable(StringSlice(data))
- b.StopTimer()
- }
-}
-
-func BenchmarkSortInt1K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]int, 1<<10)
- for i := 0; i < len(data); i++ {
- data[i] = i ^ 0x2cc
- }
- b.StartTimer()
- Ints(data)
- b.StopTimer()
- }
-}
-
-func BenchmarkStableInt1K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]int, 1<<10)
- for i := 0; i < len(data); i++ {
- data[i] = i ^ 0x2cc
- }
- b.StartTimer()
- Stable(IntSlice(data))
- b.StopTimer()
- }
-}
-
-func BenchmarkSortInt64K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]int, 1<<16)
- for i := 0; i < len(data); i++ {
- data[i] = i ^ 0xcccc
- }
- b.StartTimer()
- Ints(data)
- b.StopTimer()
- }
-}
-
-func BenchmarkStableInt64K(b *testing.B) {
- b.StopTimer()
- for i := 0; i < b.N; i++ {
- data := make([]int, 1<<16)
- for i := 0; i < len(data); i++ {
- data[i] = i ^ 0xcccc
- }
- b.StartTimer()
- Stable(IntSlice(data))
- b.StopTimer()
- }
-}
-
-const (
- _Sawtooth = iota
- _Rand
- _Stagger
- _Plateau
- _Shuffle
- _NDist
-)
-
-const (
- _Copy = iota
- _Reverse
- _ReverseFirstHalf
- _ReverseSecondHalf
- _Sorted
- _Dither
- _NMode
-)
-
-type testingData struct {
- desc string
- t *testing.T
- data []int
- maxswap int // number of swaps allowed
- ncmp, nswap int
-}
-
-func (d *testingData) Len() int { return len(d.data) }
-func (d *testingData) Less(i, j int) bool {
- d.ncmp++
- return d.data[i] < d.data[j]
-}
-func (d *testingData) Swap(i, j int) {
- if d.nswap >= d.maxswap {
- d.t.Errorf("%s: used %d swaps sorting slice of %d", d.desc, d.nswap, len(d.data))
- d.t.FailNow()
- }
- d.nswap++
- d.data[i], d.data[j] = d.data[j], d.data[i]
-}
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-func lg(n int) int {
- i := 0
- for 1<<uint(i) < n {
- i++
- }
- return i
-}
-
-func testBentleyMcIlroy(t *testing.T, sort func(Interface), maxswap func(int) int) {
- sizes := []int{100, 1023, 1024, 1025}
- if testing.Short() {
- sizes = []int{100, 127, 128, 129}
- }
- dists := []string{"sawtooth", "rand", "stagger", "plateau", "shuffle"}
- modes := []string{"copy", "reverse", "reverse1", "reverse2", "sort", "dither"}
- var tmp1, tmp2 [1025]int
- for _, n := range sizes {
- for m := 1; m < 2*n; m *= 2 {
- for dist := 0; dist < _NDist; dist++ {
- j := 0
- k := 1
- data := tmp1[0:n]
- for i := 0; i < n; i++ {
- switch dist {
- case _Sawtooth:
- data[i] = i % m
- case _Rand:
- data[i] = rand.Intn(m)
- case _Stagger:
- data[i] = (i*m + i) % n
- case _Plateau:
- data[i] = min(i, m)
- case _Shuffle:
- if rand.Intn(m) != 0 {
- j += 2
- data[i] = j
- } else {
- k += 2
- data[i] = k
- }
- }
- }
-
- mdata := tmp2[0:n]
- for mode := 0; mode < _NMode; mode++ {
- switch mode {
- case _Copy:
- for i := 0; i < n; i++ {
- mdata[i] = data[i]
- }
- case _Reverse:
- for i := 0; i < n; i++ {
- mdata[i] = data[n-i-1]
- }
- case _ReverseFirstHalf:
- for i := 0; i < n/2; i++ {
- mdata[i] = data[n/2-i-1]
- }
- for i := n / 2; i < n; i++ {
- mdata[i] = data[i]
- }
- case _ReverseSecondHalf:
- for i := 0; i < n/2; i++ {
- mdata[i] = data[i]
- }
- for i := n / 2; i < n; i++ {
- mdata[i] = data[n-(i-n/2)-1]
- }
- case _Sorted:
- for i := 0; i < n; i++ {
- mdata[i] = data[i]
- }
- // Ints is known to be correct
- // because mode Sort runs after mode _Copy.
- Ints(mdata)
- case _Dither:
- for i := 0; i < n; i++ {
- mdata[i] = data[i] + i%5
- }
- }
-
- desc := fmt.Sprintf("n=%d m=%d dist=%s mode=%s", n, m, dists[dist], modes[mode])
- d := &testingData{desc: desc, t: t, data: mdata[0:n], maxswap: maxswap(n)}
- sort(d)
- // Uncomment if you are trying to improve the number of compares/swaps.
- //t.Logf("%s: ncmp=%d, nswp=%d", desc, d.ncmp, d.nswap)
-
- // If we were testing C qsort, we'd have to make a copy
- // of the slice and sort it ourselves and then compare
- // x against it, to ensure that qsort was only permuting
- // the data, not (for example) overwriting it with zeros.
- //
- // In go, we don't have to be so paranoid: since the only
- // mutating method Sort can call is TestingData.swap,
- // it suffices here just to check that the final slice is sorted.
- if !IntsAreSorted(mdata) {
- t.Errorf("%s: ints not sorted", desc)
- t.Errorf("\t%v", mdata)
- t.FailNow()
- }
- }
- }
- }
- }
-}
-
-func TestSortBM(t *testing.T) {
- testBentleyMcIlroy(t, Sort, func(n int) int { return n * lg(n) * 12 / 10 })
-}
-
-func TestHeapsortBM(t *testing.T) {
- testBentleyMcIlroy(t, Heapsort, func(n int) int { return n * lg(n) * 12 / 10 })
-}
-
-func TestStableBM(t *testing.T) {
- testBentleyMcIlroy(t, Stable, func(n int) int { return n * lg(n) * lg(n) / 3 })
-}
-
-// This is based on the "antiquicksort" implementation by M. Douglas McIlroy.
-// See http://www.cs.dartmouth.edu/~doug/mdmspe.pdf for more info.
-type adversaryTestingData struct {
- data []int
- keys map[int]int
- candidate int
-}
-
-func (d *adversaryTestingData) Len() int { return len(d.data) }
-
-func (d *adversaryTestingData) Less(i, j int) bool {
- if _, present := d.keys[i]; !present {
- if _, present := d.keys[j]; !present {
- if i == d.candidate {
- d.keys[i] = len(d.keys)
- } else {
- d.keys[j] = len(d.keys)
- }
- }
- }
-
- if _, present := d.keys[i]; !present {
- d.candidate = i
- return false
- }
- if _, present := d.keys[j]; !present {
- d.candidate = j
- return true
- }
-
- return d.keys[i] >= d.keys[j]
-}
-
-func (d *adversaryTestingData) Swap(i, j int) {
- d.data[i], d.data[j] = d.data[j], d.data[i]
-}
-
-func TestAdversary(t *testing.T) {
- const size = 100
- data := make([]int, size)
- for i := 0; i < size; i++ {
- data[i] = i
- }
-
- d := &adversaryTestingData{data, make(map[int]int), 0}
- Sort(d) // This should degenerate to heapsort.
-}
-
-func TestStableInts(t *testing.T) {
- data := ints
- Stable(IntSlice(data[0:]))
- if !IntsAreSorted(data[0:]) {
- t.Errorf("nsorted %v\n got %v", ints, data)
- }
-}
-
-type intPairs []struct {
- a, b int
-}
-
-// IntPairs compare on a only.
-func (d intPairs) Len() int { return len(d) }
-func (d intPairs) Less(i, j int) bool { return d[i].a < d[j].a }
-func (d intPairs) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
-
-// Record initial order in B.
-func (d intPairs) initB() {
- for i := range d {
- d[i].b = i
- }
-}
-
-// InOrder checks if a-equal elements were not reordered.
-func (d intPairs) inOrder() bool {
- lastA, lastB := -1, 0
- for i := 0; i < len(d); i++ {
- if lastA != d[i].a {
- lastA = d[i].a
- lastB = d[i].b
- continue
- }
- if d[i].b <= lastB {
- return false
- }
- lastB = d[i].b
- }
- return true
-}
-
-func TestStability(t *testing.T) {
- n, m := 100000, 1000
- if testing.Short() {
- n, m = 1000, 100
- }
- data := make(intPairs, n)
-
- // random distribution
- for i := 0; i < len(data); i++ {
- data[i].a = rand.Intn(m)
- }
- if IsSorted(data) {
- t.Fatalf("terrible rand.rand")
- }
- data.initB()
- Stable(data)
- if !IsSorted(data) {
- t.Errorf("Stable didn't sort %d ints", n)
- }
- if !data.inOrder() {
- t.Errorf("Stable wasn't stable on %d ints", n)
- }
-
- // already sorted
- data.initB()
- Stable(data)
- if !IsSorted(data) {
- t.Errorf("Stable shuffeled sorted %d ints (order)", n)
- }
- if !data.inOrder() {
- t.Errorf("Stable shuffeled sorted %d ints (stability)", n)
- }
-
- // sorted reversed
- for i := 0; i < len(data); i++ {
- data[i].a = len(data) - i
- }
- data.initB()
- Stable(data)
- if !IsSorted(data) {
- t.Errorf("Stable didn't sort %d ints", n)
- }
- if !data.inOrder() {
- t.Errorf("Stable wasn't stable on %d ints", n)
- }
-}
-
-var countOpsSizes = []int{1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5, 3e5, 1e6}
-
-func countOps(t *testing.T, algo func(Interface), name string) {
- sizes := countOpsSizes
- if testing.Short() {
- sizes = sizes[:5]
- }
- if !testing.Verbose() {
- t.Skip("Counting skipped as non-verbose mode.")
- }
- for _, n := range sizes {
- td := testingData{
- desc: name,
- t: t,
- data: make([]int, n),
- maxswap: 1<<31 - 1,
- }
- for i := 0; i < n; i++ {
- td.data[i] = rand.Intn(n / 5)
- }
- algo(&td)
- t.Logf("%s %8d elements: %11d Swap, %10d Less", name, n, td.nswap, td.ncmp)
- }
-}
-
-func TestCountStableOps(t *testing.T) { countOps(t, Stable, "Stable") }
-func TestCountSortOps(t *testing.T) { countOps(t, Sort, "Sort ") }
-
-func bench(b *testing.B, size int, algo func(Interface), name string) {
- b.StopTimer()
- data := make(intPairs, size)
- x := ^uint32(0)
- for i := 0; i < b.N; i++ {
- for n := size - 3; n <= size+3; n++ {
- for i := 0; i < len(data); i++ {
- x += x
- x ^= 1
- if int32(x) < 0 {
- x ^= 0x88888eef
- }
- data[i].a = int(x % uint32(n/5))
- }
- data.initB()
- b.StartTimer()
- algo(data)
- b.StopTimer()
- if !IsSorted(data) {
- b.Errorf("%s did not sort %d ints", name, n)
- }
- if name == "Stable" && !data.inOrder() {
- b.Errorf("%s unstable on %d ints", name, n)
- }
- }
- }
-}
-
-func BenchmarkSort1e2(b *testing.B) { bench(b, 1e2, Sort, "Sort") }
-func BenchmarkStable1e2(b *testing.B) { bench(b, 1e2, Stable, "Stable") }
-func BenchmarkSort1e4(b *testing.B) { bench(b, 1e4, Sort, "Sort") }
-func BenchmarkStable1e4(b *testing.B) { bench(b, 1e4, Stable, "Stable") }
-func BenchmarkSort1e6(b *testing.B) { bench(b, 1e6, Sort, "Sort") }
-func BenchmarkStable1e6(b *testing.B) { bench(b, 1e6, Stable, "Stable") }