code: func MultithreadedSortComparators(comparators Comparators) Comparators {
  	toBeSorted := make(Comparators, len(comparators))
  	copy(toBeSorted, comparators)
  
  	var wg sync.WaitGroup
  
  	numCPU := int64(runtime.NumCPU())
  	if numCPU%2 == 1 { // single core machine
  		numCPU++
  	}
  
  	chunks := chunk(toBeSorted, numCPU)
  	wg.Add(len(chunks))
  	for i := 0; i < len(chunks); i++ {
  		go func(i int) {
  			sortBucket(chunks[i])
  			wg.Done()
  		}(i)
  	}
  
  	wg.Wait()
  	todo := make([]Comparators, len(chunks)/2)
  	for {
  		todo = todo[:len(chunks)/2]
  		wg.Add(len(chunks) / 2)
  		for i := 0; i < len(chunks); i += 2 {
  			go func(i int) {
  				todo[i/2] = SymMerge(chunks[i], chunks[i+1])
  				wg.Done()
  			}(i)
  		}
  
  		wg.Wait()
  
  		chunks = copyChunk(todo)
  		if len(chunks) == 1 {
  			break
  		}
  	}
  
  	return chunks[0]
  }
docs: // MultithreadedSortComparators will take a list of comparators
  // and sort it using as many threads as are available.  The list
  // is split into buckets for a bucket sort and then recursively
  // merged using SymMerge.