github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/cmap/cmap_bench_test.go (about)

     1  package cmap
     2  
     3  import (
     4  	"strconv"
     5  	"sync"
     6  	"testing"
     7  )
     8  
     9  func BenchmarkItems(b *testing.B) {
    10  	m := New()
    11  
    12  	// Insert 100 elements.
    13  	for i := 0; i < 10000; i++ {
    14  		m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)})
    15  	}
    16  	for i := 0; i < b.N; i++ {
    17  		m.Items()
    18  	}
    19  }
    20  
    21  func BenchmarkMarshalJson(b *testing.B) {
    22  	m := New()
    23  
    24  	// Insert 100 elements.
    25  	for i := 0; i < 10000; i++ {
    26  		m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)})
    27  	}
    28  	for i := 0; i < b.N; i++ {
    29  		_, err := m.MarshalJSON()
    30  		if err != nil {
    31  			b.FailNow()
    32  		}
    33  	}
    34  }
    35  
    36  func BenchmarkStrconv(b *testing.B) {
    37  	for i := 0; i < b.N; i++ {
    38  		strconv.Itoa(i)
    39  	}
    40  }
    41  
    42  func BenchmarkSingleInsertAbsent(b *testing.B) {
    43  	m := New()
    44  	b.ResetTimer()
    45  	for i := 0; i < b.N; i++ {
    46  		m.Set(strconv.Itoa(i), "value")
    47  	}
    48  }
    49  
    50  func BenchmarkSingleInsertAbsentSyncMap(b *testing.B) {
    51  	var m sync.Map
    52  	b.ResetTimer()
    53  	for i := 0; i < b.N; i++ {
    54  		m.Store(strconv.Itoa(i), "value")
    55  	}
    56  }
    57  
    58  func BenchmarkSingleInsertPresent(b *testing.B) {
    59  	m := New()
    60  	m.Set("key", "value")
    61  	b.ResetTimer()
    62  	for i := 0; i < b.N; i++ {
    63  		m.Set("key", "value")
    64  	}
    65  }
    66  
    67  func BenchmarkSingleInsertPresentSyncMap(b *testing.B) {
    68  	var m sync.Map
    69  	m.Store("key", "value")
    70  	b.ResetTimer()
    71  	for i := 0; i < b.N; i++ {
    72  		m.Store("key", "value")
    73  	}
    74  }
    75  
    76  func benchmarkMultiInsertDifferent(shardsCount int, b *testing.B) {
    77  	m := New(WithShardCount(shardsCount))
    78  	finished := make(chan struct{}, b.N)
    79  	_, set := GetSet(m, finished)
    80  	b.ResetTimer()
    81  	for i := 0; i < b.N; i++ {
    82  		go set(strconv.Itoa(i), "value")
    83  	}
    84  	for i := 0; i < b.N; i++ {
    85  		<-finished
    86  	}
    87  }
    88  
    89  func BenchmarkMultiInsertDifferentSyncMap(b *testing.B) {
    90  	var m sync.Map
    91  	finished := make(chan struct{}, b.N)
    92  	_, set := GetSetSyncMap(&m, finished)
    93  
    94  	b.ResetTimer()
    95  	for i := 0; i < b.N; i++ {
    96  		go set(strconv.Itoa(i), "value")
    97  	}
    98  	for i := 0; i < b.N; i++ {
    99  		<-finished
   100  	}
   101  }
   102  
   103  func BenchmarkMultiInsertDifferent_1_Shard(b *testing.B) {
   104  	runWithShards(benchmarkMultiInsertDifferent, b, 1)
   105  }
   106  
   107  func BenchmarkMultiInsertDifferent_16_Shard(b *testing.B) {
   108  	runWithShards(benchmarkMultiInsertDifferent, b, 16)
   109  }
   110  
   111  func BenchmarkMultiInsertDifferent_32_Shard(b *testing.B) {
   112  	runWithShards(benchmarkMultiInsertDifferent, b, 32)
   113  }
   114  
   115  func BenchmarkMultiInsertDifferent_256_Shard(b *testing.B) {
   116  	runWithShards(benchmarkMultiGetSetDifferent, b, 256)
   117  }
   118  
   119  func BenchmarkMultiInsertSame(b *testing.B) {
   120  	m := New()
   121  	finished := make(chan struct{}, b.N)
   122  	_, set := GetSet(m, finished)
   123  	m.Set("key", "value")
   124  	b.ResetTimer()
   125  	for i := 0; i < b.N; i++ {
   126  		go set("key", "value")
   127  	}
   128  	for i := 0; i < b.N; i++ {
   129  		<-finished
   130  	}
   131  }
   132  
   133  func BenchmarkMultiInsertSameSyncMap(b *testing.B) {
   134  	var m sync.Map
   135  	finished := make(chan struct{}, b.N)
   136  	_, set := GetSetSyncMap(&m, finished)
   137  	m.Store("key", "value")
   138  	b.ResetTimer()
   139  	for i := 0; i < b.N; i++ {
   140  		go set("key", "value")
   141  	}
   142  	for i := 0; i < b.N; i++ {
   143  		<-finished
   144  	}
   145  }
   146  
   147  func BenchmarkMultiGetSame(b *testing.B) {
   148  	m := New()
   149  	finished := make(chan struct{}, b.N)
   150  	get, _ := GetSet(m, finished)
   151  	m.Set("key", "value")
   152  	b.ResetTimer()
   153  	for i := 0; i < b.N; i++ {
   154  		go get("key", "value")
   155  	}
   156  	for i := 0; i < b.N; i++ {
   157  		<-finished
   158  	}
   159  }
   160  
   161  func BenchmarkMultiGetSameSyncMap(b *testing.B) {
   162  	var m sync.Map
   163  	finished := make(chan struct{}, b.N)
   164  	get, _ := GetSetSyncMap(&m, finished)
   165  	m.Store("key", "value")
   166  	b.ResetTimer()
   167  	for i := 0; i < b.N; i++ {
   168  		go get("key", "value")
   169  	}
   170  	for i := 0; i < b.N; i++ {
   171  		<-finished
   172  	}
   173  }
   174  
   175  func benchmarkMultiGetSetDifferent(shardsCount int, b *testing.B) {
   176  	m := New(WithShardCount(shardsCount))
   177  	finished := make(chan struct{}, 2*b.N)
   178  	get, set := GetSet(m, finished)
   179  	m.Set("-1", "value")
   180  	b.ResetTimer()
   181  	for i := 0; i < b.N; i++ {
   182  		go set(strconv.Itoa(i-1), "value")
   183  		go get(strconv.Itoa(i), "value")
   184  	}
   185  	for i := 0; i < 2*b.N; i++ {
   186  		<-finished
   187  	}
   188  }
   189  
   190  func BenchmarkMultiGetSetDifferentSyncMap(b *testing.B) {
   191  	var m sync.Map
   192  	finished := make(chan struct{}, 2*b.N)
   193  	get, set := GetSetSyncMap(&m, finished)
   194  	m.Store("-1", "value")
   195  	b.ResetTimer()
   196  	for i := 0; i < b.N; i++ {
   197  		go set(strconv.Itoa(i-1), "value")
   198  		go get(strconv.Itoa(i), "value")
   199  	}
   200  	for i := 0; i < 2*b.N; i++ {
   201  		<-finished
   202  	}
   203  }
   204  
   205  func BenchmarkMultiGetSetDifferent_1_Shard(b *testing.B) {
   206  	runWithShards(benchmarkMultiGetSetDifferent, b, 1)
   207  }
   208  
   209  func BenchmarkMultiGetSetDifferent_16_Shard(b *testing.B) {
   210  	runWithShards(benchmarkMultiGetSetDifferent, b, 16)
   211  }
   212  
   213  func BenchmarkMultiGetSetDifferent_32_Shard(b *testing.B) {
   214  	runWithShards(benchmarkMultiGetSetDifferent, b, 32)
   215  }
   216  
   217  func BenchmarkMultiGetSetDifferent_256_Shard(b *testing.B) {
   218  	runWithShards(benchmarkMultiGetSetDifferent, b, 256)
   219  }
   220  
   221  func benchmarkMultiGetSetBlock(shardsCount int, b *testing.B) {
   222  	m := New(WithShardCount(shardsCount))
   223  	finished := make(chan struct{}, 2*b.N)
   224  	get, set := GetSet(m, finished)
   225  	for i := 0; i < b.N; i++ {
   226  		m.Set(strconv.Itoa(i%100), "value")
   227  	}
   228  	b.ResetTimer()
   229  	for i := 0; i < b.N; i++ {
   230  		go set(strconv.Itoa(i%100), "value")
   231  		go get(strconv.Itoa(i%100), "value")
   232  	}
   233  	for i := 0; i < 2*b.N; i++ {
   234  		<-finished
   235  	}
   236  }
   237  
   238  func BenchmarkMultiGetSetBlockSyncMap(b *testing.B) {
   239  	var m sync.Map
   240  	finished := make(chan struct{}, 2*b.N)
   241  	get, set := GetSetSyncMap(&m, finished)
   242  	for i := 0; i < b.N; i++ {
   243  		m.Store(strconv.Itoa(i%100), "value")
   244  	}
   245  	b.ResetTimer()
   246  	for i := 0; i < b.N; i++ {
   247  		go set(strconv.Itoa(i%100), "value")
   248  		go get(strconv.Itoa(i%100), "value")
   249  	}
   250  	for i := 0; i < 2*b.N; i++ {
   251  		<-finished
   252  	}
   253  }
   254  
   255  func BenchmarkMultiGetSetBlock_1_Shard(b *testing.B) {
   256  	runWithShards(benchmarkMultiGetSetBlock, b, 1)
   257  }
   258  
   259  func BenchmarkMultiGetSetBlock_16_Shard(b *testing.B) {
   260  	runWithShards(benchmarkMultiGetSetBlock, b, 16)
   261  }
   262  
   263  func BenchmarkMultiGetSetBlock_32_Shard(b *testing.B) {
   264  	runWithShards(benchmarkMultiGetSetBlock, b, 32)
   265  }
   266  
   267  func BenchmarkMultiGetSetBlock_256_Shard(b *testing.B) {
   268  	runWithShards(benchmarkMultiGetSetBlock, b, 256)
   269  }
   270  
   271  func GetSet(m *Map, finished chan struct{}) (set func(key, value string), get func(key, value string)) {
   272  	return func(key, value string) {
   273  			for i := 0; i < 10; i++ {
   274  				m.Get(key)
   275  			}
   276  			finished <- struct{}{}
   277  		}, func(key, value string) {
   278  			for i := 0; i < 10; i++ {
   279  				m.Set(key, value)
   280  			}
   281  			finished <- struct{}{}
   282  		}
   283  }
   284  
   285  func GetSetSyncMap(m *sync.Map, finished chan struct{}) (get func(key, value string), set func(key, value string)) {
   286  	get = func(key, value string) {
   287  		for i := 0; i < 10; i++ {
   288  			m.Load(key)
   289  		}
   290  		finished <- struct{}{}
   291  	}
   292  	set = func(key, value string) {
   293  		for i := 0; i < 10; i++ {
   294  			m.Store(key, value)
   295  		}
   296  		finished <- struct{}{}
   297  	}
   298  	return
   299  }
   300  
   301  func runWithShards(bench func(shardsCount int, b *testing.B), b *testing.B, shardsCount int) {
   302  	bench(shardsCount, b)
   303  }
   304  
   305  func BenchmarkKeys(b *testing.B) {
   306  	m := New()
   307  
   308  	// Insert 100 elements.
   309  	for i := 0; i < 10000; i++ {
   310  		m.Set(strconv.Itoa(i), animal{strconv.Itoa(i)})
   311  	}
   312  	for i := 0; i < b.N; i++ {
   313  		m.Keys()
   314  	}
   315  }