Skip to content

Commit c399d76

Browse files
Merge pull request #60 from noxiouz/improve_set
Tiny Set optimizations
2 parents 82e73db + cc09fcc commit c399d76

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

set/dict.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var pool = sync.Pool{}
2929

3030
// Set is an implementation of ISet using the builtin map type. Set is threadsafe.
3131
type Set struct {
32-
items map[interface{}]bool
32+
items map[interface{}]struct{}
3333
lock sync.RWMutex
3434
flattened []interface{}
3535
}
@@ -41,7 +41,7 @@ func (set *Set) Add(items ...interface{}) {
4141

4242
set.flattened = nil
4343
for _, item := range items {
44-
set.items[item] = true
44+
set.items[item] = struct{}{}
4545
}
4646
}
4747

@@ -59,9 +59,11 @@ func (set *Set) Remove(items ...interface{}) {
5959
// Exists returns a bool indicating if the given item exists in the set.
6060
func (set *Set) Exists(item interface{}) bool {
6161
set.lock.RLock()
62-
defer set.lock.RUnlock()
6362

6463
_, ok := set.items[item]
64+
65+
set.lock.RUnlock()
66+
6567
return ok
6668
}
6769

@@ -84,17 +86,21 @@ func (set *Set) Flatten() []interface{} {
8486
// Len returns the number of items in the set.
8587
func (set *Set) Len() int64 {
8688
set.lock.RLock()
87-
defer set.lock.RUnlock()
8889

89-
return int64(len(set.items))
90+
size := int64(len(set.items))
91+
92+
set.lock.RUnlock()
93+
94+
return size
9095
}
9196

9297
// Clear will remove all items from the set.
9398
func (set *Set) Clear() {
9499
set.lock.Lock()
95-
defer set.lock.Unlock()
96100

97-
set.items = map[interface{}]bool{}
101+
set.items = map[interface{}]struct{}{}
102+
103+
set.lock.Unlock()
98104
}
99105

100106
// All returns a bool indicating if all of the supplied items exist in the set.
@@ -134,7 +140,7 @@ func (set *Set) Dispose() {
134140
func New(items ...interface{}) *Set {
135141
set := pool.Get().(*Set)
136142
for _, item := range items {
137-
set.items[item] = true
143+
set.items[item] = struct{}{}
138144
}
139145

140146
return set
@@ -143,7 +149,7 @@ func New(items ...interface{}) *Set {
143149
func init() {
144150
pool.New = func() interface{} {
145151
return &Set{
146-
items: make(map[interface{}]bool, 10),
152+
items: make(map[interface{}]struct{}, 10),
147153
}
148154
}
149155
}

set/dict_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,33 @@ func BenchmarkFlatten(b *testing.B) {
176176
set.Flatten()
177177
}
178178
}
179+
180+
func BenchmarkLen(b *testing.B) {
181+
set := New()
182+
for i := 0; i < 50; i++ {
183+
item := strconv.Itoa(i)
184+
set.Add(item)
185+
}
186+
187+
b.ResetTimer()
188+
for i := 0; i < b.N; i++ {
189+
set.Len()
190+
}
191+
}
192+
193+
func BenchmarkExists(b *testing.B) {
194+
set := New()
195+
set.Add(1)
196+
197+
b.ResetTimer()
198+
for i := 0; i < b.N; i++ {
199+
set.Exists(1)
200+
}
201+
}
202+
203+
func BenchmarkClear(b *testing.B) {
204+
set := New()
205+
for i := 0; i < b.N; i++ {
206+
set.Clear()
207+
}
208+
}

0 commit comments

Comments
 (0)