-
Notifications
You must be signed in to change notification settings - Fork 39
/
counter_test.go
123 lines (110 loc) · 2.33 KB
/
counter_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package xsync_test
import (
"runtime"
"sync/atomic"
"testing"
. "github.com/puzpuzpuz/xsync/v3"
)
func TestCounterInc(t *testing.T) {
c := NewCounter()
for i := 0; i < 100; i++ {
if v := c.Value(); v != int64(i) {
t.Fatalf("got %v, want %d", v, i)
}
c.Inc()
}
}
func TestCounterDec(t *testing.T) {
c := NewCounter()
for i := 0; i < 100; i++ {
if v := c.Value(); v != int64(-i) {
t.Fatalf("got %v, want %d", v, -i)
}
c.Dec()
}
}
func TestCounterAdd(t *testing.T) {
c := NewCounter()
for i := 0; i < 100; i++ {
if v := c.Value(); v != int64(i*42) {
t.Fatalf("got %v, want %d", v, i*42)
}
c.Add(42)
}
}
func TestCounterReset(t *testing.T) {
c := NewCounter()
c.Add(42)
if v := c.Value(); v != 42 {
t.Fatalf("got %v, want %d", v, 42)
}
c.Reset()
if v := c.Value(); v != 0 {
t.Fatalf("got %v, want %d", v, 0)
}
}
func parallelIncrementor(c *Counter, numIncs int, cdone chan bool) {
for i := 0; i < numIncs; i++ {
c.Inc()
}
cdone <- true
}
func doTestParallelIncrementors(t *testing.T, numModifiers, gomaxprocs int) {
runtime.GOMAXPROCS(gomaxprocs)
c := NewCounter()
cdone := make(chan bool)
numIncs := 10_000
for i := 0; i < numModifiers; i++ {
go parallelIncrementor(c, numIncs, cdone)
}
// Wait for the goroutines to finish.
for i := 0; i < numModifiers; i++ {
<-cdone
}
expected := int64(numModifiers * numIncs)
if v := c.Value(); v != expected {
t.Fatalf("got %d, want %d", v, expected)
}
}
func TestCounterParallelIncrementors(t *testing.T) {
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
doTestParallelIncrementors(t, 4, 2)
doTestParallelIncrementors(t, 16, 4)
doTestParallelIncrementors(t, 64, 8)
}
func benchmarkCounter(b *testing.B, writeRatio int) {
c := NewCounter()
runParallel(b, func(pb *testing.PB) {
foo := 0
for pb.Next() {
foo++
if writeRatio > 0 && foo%writeRatio == 0 {
c.Value()
} else {
c.Inc()
}
}
_ = foo
})
}
func BenchmarkCounter(b *testing.B) {
benchmarkCounter(b, 10000)
}
func benchmarkAtomicInt64(b *testing.B, writeRatio int) {
var c int64
runParallel(b, func(pb *testing.PB) {
foo := 0
for pb.Next() {
foo++
if writeRatio > 0 && foo%writeRatio == 0 {
atomic.LoadInt64(&c)
} else {
atomic.AddInt64(&c, 1)
}
}
_ = foo
})
}
func BenchmarkAtomicInt64(b *testing.B) {
benchmarkAtomicInt64(b, 10000)
}