From 5a6e13b9f15942c603d70adb27c81d21a0e505b5 Mon Sep 17 00:00:00 2001 From: bloeys Date: Sat, 11 Jun 2022 07:38:50 +0400 Subject: [PATCH] Optimize GetIntersections+GetAllElements+bench+readme --- .res/bench-getAllElements-1-million.png | Bin 0 -> 40957 bytes README.md | 11 ++- nset.go | 64 +++++++++--- nset_test.go | 126 +++++++++++++++++++++++- 4 files changed, 186 insertions(+), 15 deletions(-) create mode 100755 .res/bench-getAllElements-1-million.png diff --git a/.res/bench-getAllElements-1-million.png b/.res/bench-getAllElements-1-million.png new file mode 100755 index 0000000000000000000000000000000000000000..d454ff651d6554263d6db994a05ffc24a0d3a2e2 GIT binary patch literal 40957 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 OFB6P~LAl 0 { - outSet.Add(firstStorageUnitValue + k) - // fmt.Printf("Bucket=%d, Storage unit=%d, bitPos=%d, value=%d\n", i, j, k, firstStorageUnitValue+k) + newB.StorageUnitCount += storageUnitsToAdd + outSet.StorageUnitCount += storageUnitsToAdd + } + + newB.Data[j] = b1.Data[j] & b2.Data[j] + } + } + + return outSet +} + +//GetAllElements returns all the added numbers added to NSet. +//NOTE: Be careful with this if you have a lot of elements in NSet because NSet is compressed while the returned array is not. +//In the worst case (all uint32s stored) the returned array will be ~4.2 billion elements and will use 16+ GBs of RAM. +func (n *NSet[T]) GetAllElements() []T { + + elements := make([]T, 0) + + for i := 0; i < BucketCount; i++ { + + //bucketIndexBits are the bits removed from the original value to use for bucket indexing. + //We will use this to restore the original value 'x' once an intersection is detected + bucketIndexBits := T(i << n.shiftAmount) + + b1 := &n.Buckets[i] + for j := 0; j < len(b1.Data); j++ { + + storageUnit := b1.Data[j] + onesCount := bits.OnesCount64(uint64(storageUnit)) + if onesCount == 0 { + continue + } + elementsToAdd := make([]T, 0, onesCount) + + mask := StorageType(1 << 0) //This will be used to check set bits. Numbers will be reconstructed only for set bits + firstStorageUnitValue := T(j*StorageTypeBits) | bucketIndexBits //StorageUnitIndex = noBucketBitsX / StorageTypeBits. So: noBucketBitsX = StorageUnitIndex * StorageTypeBits; Then: x = noBucketBitsX | bucketIndexBits + + for k := T(0); onesCount > 0 && k < StorageTypeBits; k++ { + + if storageUnit&mask > 0 { + elementsToAdd = append(elementsToAdd, firstStorageUnitValue+k) + onesCount-- } mask <<= 1 } + elements = append(elements, elementsToAdd...) } } - return outSet + return elements } func (n *NSet[T]) IsEq(otherSet *NSet[T]) bool { diff --git a/nset_test.go b/nset_test.go index f4fc0d8..7d5f6de 100755 --- a/nset_test.go +++ b/nset_test.go @@ -55,7 +55,11 @@ func TestNSet(t *testing.T) { n5.AddMany(0, 1, 63, 64, math.MaxUint32) n4n5 := n4.GetIntersection(n5) - AllTrue(t, n4n5.ContainsAll(0, 1, 64, math.MaxUint32), !n4n5.Contains(63)) + + n4n5Twin := nset.NewNSet[uint32]() + n4n5Twin.AddMany(0, 1, 64, math.MaxUint32) + + AllTrue(t, n4n5.ContainsAll(0, 1, 64, math.MaxUint32), !n4n5.Contains(63), n4n5Twin.IsEq(n4n5)) //Union n6 := nset.NewNSet[uint32]() @@ -83,6 +87,13 @@ func TestNSet(t *testing.T) { n6.Union(n7) AllTrue(t, n6.IsEq(n7)) + + //GetAllElements + n8 := nset.NewNSet[uint32]() + n8.AddMany(0, 1, 55, 1000, 10000) + + n8Elements := n8.GetAllElements() + AllTrue(t, len(n8Elements) == 5, n8Elements[0] == 0, n8Elements[1] == 1, n8Elements[2] == 55, n8Elements[3] == 1000, n8Elements[4] == 10000) } func TestNSetFullRange(t *testing.T) { @@ -435,3 +446,116 @@ func BenchmarkMapIsEq(b *testing.B) { mapsAreEq(m1, m2) } } + +func BenchmarkNSetGetIntersection(b *testing.B) { + + b.StopTimer() + s1 := nset.NewNSet[uint32]() + s2 := nset.NewNSet[uint32]() + for i := uint32(0); i < maxBenchSize; i++ { + s1.Add(i) + s2.Add(i) + } + b.StartTimer() + + for i := 0; i < b.N; i++ { + s1.GetIntersection(s2) + } +} + +var elementCount int + +func BenchmarkNSetGetAllElements(b *testing.B) { + + b.StopTimer() + + s1 := nset.NewNSet[uint32]() + for i := uint32(0); i < 1000_000; i++ { + s1.Add(i) + } + b.StartTimer() + + var elements []uint32 + for i := 0; i < b.N; i++ { + elements = s1.GetAllElements() + } + + elementCount = len(elements) +} + +func BenchmarkMapGetAllElements(b *testing.B) { + + b.StopTimer() + + m1 := map[uint32]struct{}{} + for i := uint32(0); i < 1000_000; i++ { + m1[i] = struct{}{} + } + b.StartTimer() + + getElementsFunc := func(m map[uint32]struct{}) []uint32 { + + e := make([]uint32, 0, len(m)) + for k := range m { + e = append(e, k) + } + + return e + } + + var elements []uint32 + for i := 0; i < b.N; i++ { + elements = getElementsFunc(m1) + } + + elementCount = len(elements) +} + +func BenchmarkNSetGetAllElementsRand(b *testing.B) { + + b.StopTimer() + + rand.Seed(RandSeed) + s1 := nset.NewNSet[uint32]() + for i := uint32(0); i < 1000_000; i++ { + s1.Add(rand.Uint32()) + } + b.StartTimer() + + var elements []uint32 + for i := 0; i < b.N; i++ { + elements = s1.GetAllElements() + } + + elementCount = len(elements) +} + +func BenchmarkMapGetAllElementsRand(b *testing.B) { + + b.StopTimer() + + rand.Seed(RandSeed) + + m1 := map[uint32]struct{}{} + for i := uint32(0); i < 1000_000; i++ { + m1[rand.Uint32()] = struct{}{} + } + + getElementsFunc := func(m map[uint32]struct{}) []uint32 { + + e := make([]uint32, 0, len(m)) + for k := range m { + e = append(e, k) + } + + return e + } + b.StartTimer() + + var elements []uint32 + for i := 0; i < b.N; i++ { + elements = getElementsFunc(m1) + } + + elementCount = len(elements) +}