github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/container/map_bench_test.go (about) 1 package container 2 3 import ( 4 "fmt" 5 "github.com/nyan233/littlerpc/core/utils/random" 6 "strconv" 7 "testing" 8 ) 9 10 const ( 11 _Small = 1 12 _Medium = 2 13 _Large = 3 14 ) 15 16 func BenchmarkMap(b *testing.B) { 17 testOption := []struct { 18 Scheme string 19 Factory func() MapOnTest[string, int] 20 }{ 21 { 22 // RCUMap的API与其它实现不兼容, 所以inter会在运行时被替换 23 Scheme: "RCUMap", 24 }, 25 { 26 Scheme: "SyncMap118", 27 Factory: func() MapOnTest[string, int] { 28 return new(SyncMap118[string, int]) 29 }, 30 }, 31 { 32 Scheme: "MutexMap", 33 Factory: func() MapOnTest[string, int] { 34 return &MutexMap[string, int]{mp: make(map[string]int, 16384)} 35 }, 36 }, 37 { 38 Scheme: "RWMutexMap", 39 Factory: func() MapOnTest[string, int] { 40 return &RWMutexMap[string, int]{mp: make(map[interface{}]int, 16384)} 41 }, 42 }, 43 } 44 for index, opt := range testOption { 45 var rcuMap *RCUMap[string, int] 46 if index == 0 { 47 rcuMap = NewRCUMap[string, int](128) 48 opt.Factory = func() MapOnTest[string, int] { 49 return nil 50 } 51 } 52 b.Run(fmt.Sprintf("Benchmark-%s-Small-NoConcurent", opt.Scheme), benchmarkOtherMap(_Small, opt.Factory(), rcuMap, false)) 53 b.Run(fmt.Sprintf("Benchmark-%s-Small-Concurent", opt.Scheme), benchmarkOtherMap(_Small, opt.Factory(), rcuMap, true)) 54 b.Run(fmt.Sprintf("Benchmark-%s-Large-NoConcurent", opt.Scheme), benchmarkOtherMap(_Medium, opt.Factory(), rcuMap, false)) 55 b.Run(fmt.Sprintf("Benchmark-%s-Large-Concurent", opt.Scheme), benchmarkOtherMap(_Medium, opt.Factory(), rcuMap, true)) 56 b.Run(fmt.Sprintf("Benchmark-%s-Big-NoConcurent", opt.Scheme), benchmarkOtherMap(_Large, opt.Factory(), rcuMap, false)) 57 b.Run(fmt.Sprintf("Benchmark-%s-Big-Concurent", opt.Scheme), benchmarkOtherMap(_Large, opt.Factory(), rcuMap, true)) 58 } 59 } 60 61 func benchmarkOtherMap(level int, inter MapOnTest[string, int], rcuMap *RCUMap[string, int], concurrent bool) func(b *testing.B) { 62 return func(b *testing.B) { 63 var kvs []RCUMapElement[string, int] 64 switch level { 65 case _Small: 66 kvs = make([]RCUMapElement[string, int], 256) 67 case _Medium: 68 kvs = make([]RCUMapElement[string, int], 1024*16) 69 case _Large: 70 kvs = make([]RCUMapElement[string, int], 1024*128) 71 } 72 for index := range kvs { 73 kvs[index] = RCUMapElement[string, int]{ 74 Key: strconv.Itoa(index), 75 Value: index, 76 } 77 } 78 if rcuMap != nil { 79 rcuMap.StoreMulti(kvs) 80 } else { 81 for _, kv := range kvs { 82 inter.Store(kv.Key, kv.Value) 83 } 84 } 85 b.ResetTimer() 86 b.ReportAllocs() 87 b.SetParallelism(16384) 88 if concurrent { 89 b.RunParallel(func(pb *testing.PB) { 90 for pb.Next() { 91 index := int(random.FastRand()) % len(kvs) 92 if rcuMap != nil { 93 rcuMap.LoadOk(kvs[index].Key) 94 } else { 95 inter.LoadOk(kvs[index].Key) 96 } 97 } 98 }) 99 } else { 100 for i := 0; i < b.N; i++ { 101 index := int(random.FastRand()) % len(kvs) 102 if rcuMap != nil { 103 rcuMap.LoadOk(kvs[index].Key) 104 } else { 105 inter.LoadOk(kvs[index].Key) 106 } 107 } 108 } 109 } 110 }