@@ -6,66 +6,304 @@ import (
66 "testing"
77)
88
9- var K = 100000
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+ }
1020
11- func BenchmarkItemsCMap (b * testing.B ) {
21+ func BenchmarkMarshalJson (b * testing.B ) {
1222 m := New ()
1323
14- // Insert K elements.
15- for i := 0 ; i < K ; i ++ {
24+ // Insert 100 elements.
25+ for i := 0 ; i < 10000 ; i ++ {
1626 m .Set (strconv .Itoa (i ), Animal {strconv .Itoa (i )})
1727 }
18- for i := 0 ; i < K ; i ++ {
19- m .Get (strconv .Itoa (i ))
28+ for i := 0 ; i < b .N ; i ++ {
29+ _ , err := m .MarshalJSON ()
30+ if err != nil {
31+ b .FailNow ()
32+ }
2033 }
2134}
2235
23- func BenchmarkItemsSyncMap (b * testing.B ) {
24- m := sync.Map {}
36+ func BenchmarkStrconv (b * testing.B ) {
37+ for i := 0 ; i < b .N ; i ++ {
38+ strconv .Itoa (i )
39+ }
40+ }
2541
26- // Insert 100000 elements.
27- for i := 0 ; i < K ; i ++ {
28- m .Store (strconv .Itoa (i ), Animal {strconv .Itoa (i )})
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" )
2947 }
30- for i := 0 ; i < K ; i ++ {
31- m .Load (strconv .Itoa (i ))
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" )
3255 }
3356}
3457
35- func BenchmarkItemsCMapConcurrent (b * testing.B ) {
58+ func BenchmarkSingleInsertPresent (b * testing.B ) {
3659 m := New ()
37- wg := & sync.WaitGroup {}
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+ }
3875
39- for i := 0 ; i < K ; i ++ {
40- wg .Add (1 )
41- go func (i int ) {
42- m .Set (strconv .Itoa (i ), Animal {strconv .Itoa (i )})
43- wg .Done ()
44- }(i )
76+ func benchmarkMultiInsertDifferent (b * testing.B ) {
77+ m := New ()
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
4586 }
87+ }
4688
47- wg .Wait ()
89+ func BenchmarkMultiInsertDifferentSyncMap (b * testing.B ) {
90+ var m sync.Map
91+ finished := make (chan struct {}, b .N )
92+ _ , set := GetSetSyncMap (& m , finished )
4893
49- for i := 0 ; i < K ; i ++ {
50- m .Get (strconv .Itoa (i ))
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
51100 }
52101}
53102
54- func BenchmarkItemsSyncMapConcurrent (b * testing.B ) {
55- m := sync.Map {}
56- wg := & sync.WaitGroup {}
103+ func BenchmarkMultiInsertDifferent_1_Shard (b * testing.B ) {
104+ runWithShards (benchmarkMultiInsertDifferent , b , 1 )
105+ }
106+ func BenchmarkMultiInsertDifferent_16_Shard (b * testing.B ) {
107+ runWithShards (benchmarkMultiInsertDifferent , b , 16 )
108+ }
109+ func BenchmarkMultiInsertDifferent_32_Shard (b * testing.B ) {
110+ runWithShards (benchmarkMultiInsertDifferent , b , 32 )
111+ }
112+ func BenchmarkMultiInsertDifferent_256_Shard (b * testing.B ) {
113+ runWithShards (benchmarkMultiGetSetDifferent , b , 256 )
114+ }
115+
116+ func BenchmarkMultiInsertSame (b * testing.B ) {
117+ m := New ()
118+ finished := make (chan struct {}, b .N )
119+ _ , set := GetSet (m , finished )
120+ m .Set ("key" , "value" )
121+ b .ResetTimer ()
122+ for i := 0 ; i < b .N ; i ++ {
123+ go set ("key" , "value" )
124+ }
125+ for i := 0 ; i < b .N ; i ++ {
126+ <- finished
127+ }
128+ }
129+
130+ func BenchmarkMultiInsertSameSyncMap (b * testing.B ) {
131+ var m sync.Map
132+ finished := make (chan struct {}, b .N )
133+ _ , set := GetSetSyncMap (& m , finished )
134+ m .Store ("key" , "value" )
135+ b .ResetTimer ()
136+ for i := 0 ; i < b .N ; i ++ {
137+ go set ("key" , "value" )
138+ }
139+ for i := 0 ; i < b .N ; i ++ {
140+ <- finished
141+ }
142+ }
57143
58- for i := 0 ; i < K ; i ++ {
59- wg .Add (1 )
60- go func (i int ) {
61- m .Store (strconv .Itoa (i ), Animal {strconv .Itoa (i )})
62- wg .Done ()
63- }(i )
144+ func BenchmarkMultiGetSame (b * testing.B ) {
145+ m := New ()
146+ finished := make (chan struct {}, b .N )
147+ get , _ := GetSet (m , finished )
148+ m .Set ("key" , "value" )
149+ b .ResetTimer ()
150+ for i := 0 ; i < b .N ; i ++ {
151+ go get ("key" , "value" )
64152 }
153+ for i := 0 ; i < b .N ; i ++ {
154+ <- finished
155+ }
156+ }
65157
66- wg .Wait ()
158+ func BenchmarkMultiGetSameSyncMap (b * testing.B ) {
159+ var m sync.Map
160+ finished := make (chan struct {}, b .N )
161+ get , _ := GetSetSyncMap (& m , finished )
162+ m .Store ("key" , "value" )
163+ b .ResetTimer ()
164+ for i := 0 ; i < b .N ; i ++ {
165+ go get ("key" , "value" )
166+ }
167+ for i := 0 ; i < b .N ; i ++ {
168+ <- finished
169+ }
170+ }
67171
68- for i := 0 ; i < K ; i ++ {
69- m .Load (strconv .Itoa (i ))
172+ func benchmarkMultiGetSetDifferent (b * testing.B ) {
173+ m := New ()
174+ finished := make (chan struct {}, 2 * b .N )
175+ get , set := GetSet (m , finished )
176+ m .Set ("-1" , "value" )
177+ b .ResetTimer ()
178+ for i := 0 ; i < b .N ; i ++ {
179+ go set (strconv .Itoa (i - 1 ), "value" )
180+ go get (strconv .Itoa (i ), "value" )
181+ }
182+ for i := 0 ; i < 2 * b .N ; i ++ {
183+ <- finished
184+ }
185+ }
186+
187+ func BenchmarkMultiGetSetDifferentSyncMap (b * testing.B ) {
188+ var m sync.Map
189+ finished := make (chan struct {}, 2 * b .N )
190+ get , set := GetSetSyncMap (& m , finished )
191+ m .Store ("-1" , "value" )
192+ b .ResetTimer ()
193+ for i := 0 ; i < b .N ; i ++ {
194+ go set (strconv .Itoa (i - 1 ), "value" )
195+ go get (strconv .Itoa (i ), "value" )
196+ }
197+ for i := 0 ; i < 2 * b .N ; i ++ {
198+ <- finished
199+ }
200+ }
201+
202+ func BenchmarkMultiGetSetDifferent_1_Shard (b * testing.B ) {
203+ runWithShards (benchmarkMultiGetSetDifferent , b , 1 )
204+ }
205+ func BenchmarkMultiGetSetDifferent_16_Shard (b * testing.B ) {
206+ runWithShards (benchmarkMultiGetSetDifferent , b , 16 )
207+ }
208+ func BenchmarkMultiGetSetDifferent_32_Shard (b * testing.B ) {
209+ runWithShards (benchmarkMultiGetSetDifferent , b , 32 )
210+ }
211+ func BenchmarkMultiGetSetDifferent_256_Shard (b * testing.B ) {
212+ runWithShards (benchmarkMultiGetSetDifferent , b , 256 )
213+ }
214+
215+ func benchmarkMultiGetSetBlock (b * testing.B ) {
216+ m := New ()
217+ finished := make (chan struct {}, 2 * b .N )
218+ get , set := GetSet (m , finished )
219+ for i := 0 ; i < b .N ; i ++ {
220+ m .Set (strconv .Itoa (i % 100 ), "value" )
221+ }
222+ b .ResetTimer ()
223+ for i := 0 ; i < b .N ; i ++ {
224+ go set (strconv .Itoa (i % 100 ), "value" )
225+ go get (strconv .Itoa (i % 100 ), "value" )
226+ }
227+ for i := 0 ; i < 2 * b .N ; i ++ {
228+ <- finished
229+ }
230+ }
231+
232+ func BenchmarkMultiGetSetBlockSyncMap (b * testing.B ) {
233+ var m sync.Map
234+ finished := make (chan struct {}, 2 * b .N )
235+ get , set := GetSetSyncMap (& m , finished )
236+ for i := 0 ; i < b .N ; i ++ {
237+ m .Store (strconv .Itoa (i % 100 ), "value" )
238+ }
239+ b .ResetTimer ()
240+ for i := 0 ; i < b .N ; i ++ {
241+ go set (strconv .Itoa (i % 100 ), "value" )
242+ go get (strconv .Itoa (i % 100 ), "value" )
243+ }
244+ for i := 0 ; i < 2 * b .N ; i ++ {
245+ <- finished
246+ }
247+ }
248+
249+ func BenchmarkMultiGetSetBlock_1_Shard (b * testing.B ) {
250+ runWithShards (benchmarkMultiGetSetBlock , b , 1 )
251+ }
252+ func BenchmarkMultiGetSetBlock_16_Shard (b * testing.B ) {
253+ runWithShards (benchmarkMultiGetSetBlock , b , 16 )
254+ }
255+ func BenchmarkMultiGetSetBlock_32_Shard (b * testing.B ) {
256+ runWithShards (benchmarkMultiGetSetBlock , b , 32 )
257+ }
258+ func BenchmarkMultiGetSetBlock_256_Shard (b * testing.B ) {
259+ runWithShards (benchmarkMultiGetSetBlock , b , 256 )
260+ }
261+
262+ func GetSet (m ConcurrentMap , finished chan struct {}) (set func (key , value string ), get func (key , value string )) {
263+ return func (key , value string ) {
264+ for i := 0 ; i < 10 ; i ++ {
265+ m .Get (key )
266+ }
267+ finished <- struct {}{}
268+ }, func (key , value string ) {
269+ for i := 0 ; i < 10 ; i ++ {
270+ m .Set (key , value )
271+ }
272+ finished <- struct {}{}
273+ }
274+ }
275+
276+ func GetSetSyncMap (m * sync.Map , finished chan struct {}) (get func (key , value string ), set func (key , value string )) {
277+ get = func (key , value string ) {
278+ for i := 0 ; i < 10 ; i ++ {
279+ m .Load (key )
280+ }
281+ finished <- struct {}{}
282+ }
283+ set = func (key , value string ) {
284+ for i := 0 ; i < 10 ; i ++ {
285+ m .Store (key , value )
286+ }
287+ finished <- struct {}{}
288+ }
289+ return
290+ }
291+
292+ func runWithShards (bench func (b * testing.B ), b * testing.B , shardsCount int ) {
293+ oldShardsCount := SHARD_COUNT
294+ SHARD_COUNT = shardsCount
295+ bench (b )
296+ SHARD_COUNT = oldShardsCount
297+ }
298+
299+ func BenchmarkKeys (b * testing.B ) {
300+ m := New ()
301+
302+ // Insert 100 elements.
303+ for i := 0 ; i < 10000 ; i ++ {
304+ m .Set (strconv .Itoa (i ), Animal {strconv .Itoa (i )})
305+ }
306+ for i := 0 ; i < b .N ; i ++ {
307+ m .Keys ()
70308 }
71309}
0 commit comments