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  }