Better isEqual bench

This commit is contained in:
bloeys
2022-06-13 01:36:04 +04:00
parent d4b9c6d3c7
commit f47e5b3300
4 changed files with 109 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -140,8 +140,9 @@ Map benefits from sizing while NSet isn't affected, but in both cases NSet remai
Another case where NSet really shines is checking if two sets are equal. Another case where NSet really shines is checking if two sets are equal.
Below is a benchmark that checks whether two NSets/maps with 10 Million elements in each are equal (They are equal, which is the worst case). Below is a benchmark that checks whether two NSets/maps with 10 Million elements in each are equal (They are equal, which is the worst case).
Here NSet finishes in `0.1ms` but Map takes almost a second with `813ms`. Here NSet finishes in `0.1ms` but Map takes almost a second with `813ms`. With a few large numbers NSet suffers a bit but then its performance remains or even improves with more elements, while map degrades greatly.
![Benchmarking IsEq with 10,000,000 elements](./.res/bench-is-equal-10-million.png)
![Benchmarking IsEq with 10 and 100 million elements](./.res/bench-is-equal-10-100-mil.png)
Next we have `GetAllElements`, which simply returns an array of all the elements of NSet/Map (note this is dangerous in NSet. See [Memory characteristics](#memory-characteristics)). Next we have `GetAllElements`, which simply returns an array of all the elements of NSet/Map (note this is dangerous in NSet. See [Memory characteristics](#memory-characteristics)).
![Benchmarking GetAllElements with 10,000,000 elements](.res/bench-getAllElements-10-million.png) ![Benchmarking GetAllElements with 10,000,000 elements](.res/bench-getAllElements-10-million.png)

View File

@ -447,6 +447,112 @@ func BenchmarkMapIsEq(b *testing.B) {
} }
} }
func BenchmarkNSetIsEqRand(b *testing.B) {
b.StopTimer()
rand.Seed(RandSeed)
s1 := nset.NewNSet[uint32]()
s2 := nset.NewNSet[uint32]()
for i := uint32(0); i < maxBenchSize; i++ {
r := rand.Uint32()
s1.Add(r)
s2.Add(r)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
s1.IsEq(s2)
}
}
func BenchmarkMapIsEqRand(b *testing.B) {
b.StopTimer()
rand.Seed(RandSeed)
m1 := map[uint32]struct{}{}
m2 := map[uint32]struct{}{}
for i := uint32(0); i < maxBenchSize; i++ {
r := rand.Uint32()
m1[r] = struct{}{}
m2[r] = struct{}{}
}
b.StartTimer()
mapsAreEq := func(m1, m2 map[uint32]struct{}) bool {
if len(m1) != len(m2) {
return false
}
for k := range m1 {
if _, ok := m2[k]; !ok {
return false
}
}
return true
}
for i := 0; i < b.N; i++ {
mapsAreEq(m1, m2)
}
}
func BenchmarkNSetIsEqRand100Mil(b *testing.B) {
b.StopTimer()
rand.Seed(RandSeed)
s1 := nset.NewNSet[uint32]()
s2 := nset.NewNSet[uint32]()
for i := uint32(0); i < 100_000_000; i++ {
r := rand.Uint32()
s1.Add(r)
s2.Add(r)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
s1.IsEq(s2)
}
}
func BenchmarkMapIsEqRand100Mil(b *testing.B) {
b.StopTimer()
rand.Seed(RandSeed)
m1 := map[uint32]struct{}{}
m2 := map[uint32]struct{}{}
for i := uint32(0); i < 100_000_000; i++ {
r := rand.Uint32()
m1[r] = struct{}{}
m2[r] = struct{}{}
}
b.StartTimer()
mapsAreEq := func(m1, m2 map[uint32]struct{}) bool {
if len(m1) != len(m2) {
return false
}
for k := range m1 {
if _, ok := m2[k]; !ok {
return false
}
}
return true
}
for i := 0; i < b.N; i++ {
mapsAreEq(m1, m2)
}
}
var getIntersectionNset *nset.NSet[uint32] var getIntersectionNset *nset.NSet[uint32]
func BenchmarkNSetGetIntersection(b *testing.B) { func BenchmarkNSetGetIntersection(b *testing.B) {