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.
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`.
![Benchmarking IsEq with 10,000,000 elements](./.res/bench-is-equal-10-million.png)
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 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)).
![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]
func BenchmarkNSetGetIntersection(b *testing.B) {