github.com/TritonHo/qsortm@v1.0.0/experiment/qsort_test.go (about)

     1  package experiment
     2  
     3  import (
     4  	"math/rand"
     5  	"sort"
     6  	"testing"
     7  
     8  	"log"
     9  	"time"
    10  )
    11  
    12  func generateRandomSlice(n int) []int {
    13  
    14  	slice := make([]int, n, n)
    15  	for i := 0; i < n; i++ {
    16  		slice[i] = rand.Int()
    17  	}
    18  	return slice
    19  }
    20  
    21  func isAscSorted(slice []int) bool {
    22  
    23  	for i := 1; i < len(slice); i++ {
    24  		if slice[i-1] > slice[i] {
    25  			return false
    26  		}
    27  	}
    28  	return true
    29  }
    30  
    31  func sliceToCounters(slice []int) map[int]int {
    32  	counters := map[int]int{}
    33  	for _, item := range slice {
    34  		counters[item] = counters[item] + 1
    35  	}
    36  	return counters
    37  }
    38  
    39  func verifySliceCounters(slice []int, counters map[int]int) bool {
    40  	for _, item := range slice {
    41  		counters[item] = counters[item] - 1
    42  	}
    43  	for _, v := range counters {
    44  		if v != 0 {
    45  			return false
    46  		}
    47  	}
    48  	return true
    49  }
    50  
    51  func TestCountBucketSize(t *testing.T) {
    52  	input := generateRandomSlice(100000)
    53  
    54  	pivotPositions := getPivotPositions(input, 100)
    55  	pivots := countBucketSize(input, pivotPositions)
    56  
    57  	for _, v := range input {
    58  		for i := range pivots {
    59  			if v <= input[pivots[i].pos] {
    60  				pivots[i].count--
    61  				break
    62  			}
    63  		}
    64  	}
    65  	for i, p := range pivots {
    66  		if p.count != 0 {
    67  			t.Error("the count not match", i, p)
    68  		}
    69  	}
    70  	log.Println("TestCountBucketSize finished")
    71  }
    72  
    73  func TestRelocatePivots(t *testing.T) {
    74  	input := generateRandomSlice(10000)
    75  	input2 := []int{}
    76  	for _, value := range input {
    77  		input2 = append(input2, value)
    78  	}
    79  
    80  	pivotPositions := getPivotPositions(input, 100)
    81  	pivots := countBucketSize(input, pivotPositions)
    82  	mergedPivots := mergePivots(input, pivots, 10)
    83  	finalizedPivotPositions := relocatePivots(input, mergedPivots)
    84  
    85  	// get the value of the pivots
    86  	values := []int{}
    87  	for _, pos := range finalizedPivotPositions {
    88  		values = append(values, input[pos])
    89  	}
    90  
    91  	sort.Ints(input2)
    92  
    93  	// if the finalizedPivotPositions is positioned corrected, it should remain in the same location
    94  	for i, pos := range finalizedPivotPositions {
    95  		if input2[pos] != values[i] {
    96  			t.Error("the pivot position not match", input2[pos], values[i])
    97  		}
    98  	}
    99  
   100  	log.Println(`TestRelocatePivots finished`)
   101  }
   102  
   103  func TestQsortWithBucket(t *testing.T) {
   104  	array := generateRandomSlice(1000000)
   105  	counters := sliceToCounters(array)
   106  
   107  	startTime := time.Now()
   108  	qsortWithBucket(array)
   109  
   110  	log.Println("TestQsortWithBucket elapsed time:", time.Since(startTime))
   111  	if isAscSorted(array) == false {
   112  		t.Error("the sorting is buggy, isAscSorted failed")
   113  	}
   114  	if verifySliceCounters(array, counters) == false {
   115  		t.Error("the sorting is buggy, verifySliceCounters failed")
   116  	}
   117  }
   118  
   119  func TestQsortWithBucketV3(t *testing.T) {
   120  	array := generateRandomSlice(1000000)
   121  	counters := sliceToCounters(array)
   122  
   123  	startTime := time.Now()
   124  	qsortWithBucketV3(array)
   125  
   126  	log.Println("TestQsortWithBucketV3 elapsed time:", time.Since(startTime))
   127  	if isAscSorted(array) == false {
   128  		t.Error("the sorting is buggy, isAscSorted failed")
   129  	}
   130  	if verifySliceCounters(array, counters) == false {
   131  		t.Error("the sorting is buggy, verifySliceCounters failed")
   132  	}
   133  
   134  }
   135  
   136  func TestQsortProd(t *testing.T) {
   137  	array := generateRandomSlice(1000000)
   138  	counters := sliceToCounters(array)
   139  
   140  	startTime := time.Now()
   141  	qsortProd(array)
   142  
   143  	log.Println("TestQsortProd elapsed time:", time.Since(startTime))
   144  	if isAscSorted(array) == false {
   145  		t.Error("the sorting is buggy, isAscSorted failed")
   146  	}
   147  	if verifySliceCounters(array, counters) == false {
   148  		t.Error("the sorting is buggy, verifySliceCounters failed")
   149  	}
   150  }
   151  
   152  func TestQsortProdV2(t *testing.T) {
   153  	array := generateRandomSlice(1000000)
   154  	counters := sliceToCounters(array)
   155  
   156  	startTime := time.Now()
   157  	qsortProdV2(array)
   158  
   159  	log.Println("TestQsortProdV2 elapsed time:", time.Since(startTime))
   160  	if isAscSorted(array) == false {
   161  		t.Error("the sorting is buggy, isAscSorted failed")
   162  	}
   163  	if verifySliceCounters(array, counters) == false {
   164  		t.Error("the sorting is buggy, verifySliceCounters failed")
   165  	}
   166  }
   167  
   168  func BenchmarkQsortProd(b *testing.B) {
   169  	array := generateRandomSlice(1000000)
   170  	qsortProd(array)
   171  }
   172  func BenchmarkQsortProdV2(b *testing.B) {
   173  	array := generateRandomSlice(1000000)
   174  	qsortProdV2(array)
   175  }
   176  
   177  func BenchmarkQsortStandard(b *testing.B) {
   178  	array := generateRandomSlice(1000000)
   179  	sort.Ints(array)
   180  }