2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00
sonic/encoder/sort_test.go
Yi Duan a577eafc25
refactor: make it more readable (#104)
Co-authored-by: duanyi.aster <duanyi.aster@bytedance.com>
2021-09-18 11:31:25 +08:00

168 lines
4.1 KiB
Go

/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package encoder
import (
`bytes`
`math/rand`
`reflect`
`sort`
`strconv`
`testing`
`unsafe`
)
var keyLen = 15
type encodedKeyValues []encodedKV
type encodedKV struct {
key string
_MapPair []byte
}
func (sv encodedKeyValues) Len() int { return len(sv) }
func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }
func getKvs(std bool) interface{} {
var map_size = 1000
if std {
kvs := make(encodedKeyValues, map_size)
for i:=map_size-1; i>=0; i-- {
kvs[i] = encodedKV{
key: "\"test_" + strconv.Itoa(i) + "\"",
}
}
return kvs
} else {
kvs := make([]_MapPair, map_size)
for i:=map_size-1; i>=0; i-- {
kvs[i] = _MapPair{
k: "\"test_" + strconv.Itoa(i) + "\"",
}
}
return kvs
}
}
func BenchmarkSort_Sonic(b *testing.B) {
ori := getKvs(false).([]_MapPair)
kvs := make([]_MapPair, len(ori))
b.ResetTimer()
for i:=0; i<b.N; i++ {
copy(kvs, ori)
radixQsort(kvs, 0, maxDepth(len(kvs)))
}
}
func BenchmarkSort_Std(b *testing.B) {
ori := getKvs(true).(encodedKeyValues)
kvs := make(encodedKeyValues, len(ori))
b.ResetTimer()
for i:=0; i<b.N; i++ {
copy(kvs, ori)
sort.Sort(kvs)
}
}
func BenchmarkSort_Parallel_Sonic(b *testing.B) {
ori := getKvs(false).([]_MapPair)
b.ResetTimer()
b.RunParallel(func(p *testing.PB) {
kvs := make([]_MapPair, len(ori))
for p.Next() {
copy(kvs, ori)
radixQsort(kvs, 0, maxDepth(len(kvs)))
}
})
}
func BenchmarkSort_Parallel_Std(b *testing.B) {
ori := getKvs(true).(encodedKeyValues)
b.ResetTimer()
b.RunParallel(func(p *testing.PB) {
kvs := make(encodedKeyValues, len(ori))
for p.Next() {
copy(kvs, ori)
sort.Sort(kvs)
}
})
}
type kvSlice []_MapPair
// Make kvSlice meet sort.Interface.
func (self kvSlice) Less(i, j int) bool { return self[i].k < self[j].k }
func (self kvSlice) Swap(i, j int) { self[i], self[j] = self[j], self[i] }
func (self kvSlice) Len() int { return len(self) }
//go:nosplit
func (self kvSlice) Sort() {
radixQsort(self, 0, maxDepth(len(self)))
}
func (self kvSlice) String() string {
buf := bytes.NewBuffer(nil)
for i, kv := range self {
if i > 0 {
buf.WriteByte(',')
}
buf.WriteString(kv.k)
}
return buf.String()
}
func TestSort_SortRandomKeys(t *testing.T) {
kvs := getRandKvs(100, keyLen)
sorted := make([]_MapPair, len(kvs))
copy(sorted, kvs)
sort.Sort(kvSlice(sorted))
kvs.Sort()
got := kvs.String()
want := kvSlice(sorted).String()
if !reflect.DeepEqual(got, want) {
t.Errorf(" got: %v\nwant: %v\n", got, want)
}
}
func genKey(kl int) []byte {
l := int(rand.Uint32()%uint32(kl) + 2)
k := make([]byte, l)
k[0], k[l-1] = '"', '"'
for i := 1; i < l-1; i++ {
k[i] = byte('a' + int(rand.Uint32()%26))
}
return k
}
func getRandKvs(kn int, kl int) kvSlice {
keys := make(map[string]bool)
kvs := make(kvSlice, 0)
for len(keys) < kn {
k := genKey(kl)
keys[string(k)] = true
}
for k := range keys {
var kv _MapPair
kv.k = k
kv.v = unsafe.Pointer(&k)
kvs = append(kvs, kv)
}
return kvs
}