gitee.com/quant1x/num@v0.3.2/internal/partial/sort_test.go (about)

     1  package partial
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"slices"
     7  	"sort"
     8  	"testing"
     9  )
    10  
    11  func TestSort(t *testing.T) {
    12  	cases := []testCase[int]{
    13  		{[]int{}, 0},
    14  		{[]int{2}, 1},
    15  		{[]int{2, 1}, 1},
    16  		{[]int{2, 1}, 2},
    17  		{[]int{1, 1, 1}, 2},
    18  		{[]int{5, 0, 0, 0, 1}, 2},
    19  		{[]int{5, 0, 0, 0, 1}, 5},
    20  	}
    21  	rand.Seed(2)
    22  	big := make([]int, 100_000)
    23  	for i := 0; i < 100_000; i++ {
    24  		big[i] = rand.Intn(10_000)
    25  	}
    26  	cases = append(cases, testCase[int]{big, 10_000})
    27  	for _, c := range cases {
    28  		Sort(c.x, c.k)
    29  		if !slices.IsSorted(c.x[:c.k]) {
    30  			t.Errorf("Not sorted, out=%v, k=%v", c.x, c.k)
    31  		}
    32  	}
    33  }
    34  
    35  func TestSortFunc(t *testing.T) {
    36  	cases := []testCase[person]{
    37  		{[]person{{"bob", 45}, {"jane", 31}}, 1},
    38  		{[]person{{"bob", 45}, {"jane", 31}}, 2},
    39  		{[]person{{"bob", 45}, {"jane", 31}, {"karl", 39}}, 2},
    40  		{[]person{{"bob", 45}, {"jane", 31}, {"karl", 39}}, 3},
    41  	}
    42  	less := func(x, y person) int { return x.age - y.age }
    43  	for _, c := range cases {
    44  		SortFunc(c.x, c.k, less)
    45  		if !slices.IsSortedFunc(c.x[:c.k], less) {
    46  			t.Errorf("Not sorted, out=%v, k=%v", c.x, c.k)
    47  		}
    48  	}
    49  }
    50  
    51  func TestSortOutOfBounds(t *testing.T) {
    52  	less := func(x, y int) int { return x - y }
    53  
    54  	x := []int{9, 2, 5}
    55  	Sort(x, -1)
    56  	if !slices.Equal(x, []int{9, 2, 5}) {
    57  		t.Errorf("Negative k should be treated as zero and sort nothing")
    58  	}
    59  
    60  	y := []int{9, 2, 5}
    61  	SortFunc(y, 5, less)
    62  	if !slices.Equal(y, []int{2, 5, 9}) {
    63  		t.Errorf("Entire slice should be sorted when k is greater than len")
    64  	}
    65  }
    66  
    67  func BenchmarkSort(b *testing.B) {
    68  	sizes := []int{1_000, 10_000, 100_000}
    69  	k := 100
    70  	for _, size := range sizes {
    71  		var x []int
    72  		for i := 0; i < size; i++ {
    73  			x = append(x, rand.Intn(size/10))
    74  		}
    75  		b.Run(fmt.Sprintf("sort.Slice_%d", size), func(b *testing.B) {
    76  			for i := 0; i < b.N; i++ {
    77  				b.StopTimer()
    78  				y := slices.Clone(x)
    79  				b.StartTimer()
    80  				sort.Slice(y, func(i, j int) bool { return y[i] < y[j] })
    81  			}
    82  		})
    83  		b.Run(fmt.Sprintf("slices.Sort_%d", size), func(b *testing.B) {
    84  			for i := 0; i < b.N; i++ {
    85  				b.StopTimer()
    86  				y := slices.Clone(x)
    87  				b.StartTimer()
    88  				slices.Sort(y)
    89  			}
    90  		})
    91  		b.Run(fmt.Sprintf("slices.SortFunc_%d", size), func(b *testing.B) {
    92  			for i := 0; i < b.N; i++ {
    93  				b.StopTimer()
    94  				y := slices.Clone(x)
    95  				b.StartTimer()
    96  				slices.SortFunc(y, func(i, j int) int { return i - j })
    97  			}
    98  		})
    99  		b.Run(fmt.Sprintf("partial.Sort_%d", size), func(b *testing.B) {
   100  			for i := 0; i < b.N; i++ {
   101  				b.StopTimer()
   102  				y := slices.Clone(x)
   103  				b.StartTimer()
   104  				Sort(y, k)
   105  			}
   106  		})
   107  		b.Run(fmt.Sprintf("partial.SortFunc_%d", size), func(b *testing.B) {
   108  			for i := 0; i < b.N; i++ {
   109  				b.StopTimer()
   110  				y := slices.Clone(x)
   111  				b.StartTimer()
   112  				SortFunc(y, k, func(i, j int) int { return i - j })
   113  			}
   114  		})
   115  	}
   116  }