diff --git a/bench_helper_test.go b/bench_helper_test.go index 793785e..2b0e938 100644 --- a/bench_helper_test.go +++ b/bench_helper_test.go @@ -29,7 +29,7 @@ func buildCaseName(n int, safe bool) string { settype = "Unsafe" } - return fmt.Sprintf("%s(%d)", settype, n) + return fmt.Sprintf("%d_%s", n, settype) } type benchCase struct { @@ -41,8 +41,6 @@ func buildBenchCases(ns ...int) []benchCase { cases := []benchCase{} for _, n := range ns { cases = append(cases, benchCase{n, true}) - } - for _, n := range ns { cases = append(cases, benchCase{n, false}) } return cases diff --git a/bench_test.go b/bench_test.go index 318216c..2d9cb71 100644 --- a/bench_test.go +++ b/bench_test.go @@ -26,814 +26,378 @@ SOFTWARE. package mapset import ( + "math/rand" "testing" ) -func BenchmarkNewSet(b *testing.B) { - nums := nrand(1000) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = NewSet(nums...) - } -} +func BenchmarkNew(b *testing.B) { + for _, c := range []int{1, 10, 100} { + nums := nrand(c) -func BenchmarkNewThreadUnsafeSet(b *testing.B) { - nums := nrand(1000) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = NewThreadUnsafeSet(nums...) - } -} - -func benchAdd(b *testing.B, n int, newSet func(...int) Set[int]) { - nums := nrand(n) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s := newSet() - for _, v := range nums { - s.Add(v) - } + b.Run(buildCaseName(c, true), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = NewSet(nums...) + } + }) + b.Run(buildCaseName(c, false), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = NewThreadUnsafeSet(nums...) + } + }) } } -func BenchmarkAddSafe(b *testing.B) { - benchAdd(b, 1000, NewSet[int]) -} - -func BenchmarkAddUnsafe(b *testing.B) { - benchAdd(b, 1000, NewThreadUnsafeSet[int]) -} +func BenchmarkAdd(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(0, c.safe) + t := nrand(c.n) -func benchAppend(b *testing.B, n int, newSet func(...int) Set[int]) { - nums := nrand(n) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s := newSet() - s.Append(nums...) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, v := range t { + _ = s.Add(v) + } + } + }) } } -func BenchmarkAppendSafe(b *testing.B) { - benchAppend(b, 1000, NewSet[int]) -} - -func BenchmarkAppendUnsafe(b *testing.B) { - benchAppend(b, 1000, NewThreadUnsafeSet[int]) -} - -func benchAppendFrom(b *testing.B, n int, s, t Set[int]) { - s.Append(nrand(n)...) - t.Append(nrand(n)...) +func BenchmarkAppend(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(0, c.safe) + t := nrand(c.n) - b.ReportAllocs() - for i := 0; i < b.N; i++ { - _ = s.AppendFrom(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Append(t...) + } + }) } } -func BenchmarkAppendFromSafe(b *testing.B) { - benchAppendFrom(b, 1000, NewSet[int](), NewSet[int]()) -} - -func BenchmarkAppendFromUnsafe(b *testing.B) { - benchAppendFrom(b, 1000, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchRemove(b *testing.B, s Set[int]) { - nums := nrand(b.N) - for _, v := range nums { - s.Add(v) - } +func BenchmarkAppendFrom(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for _, v := range nums { - s.Remove(v) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.AppendFrom(t) + } + }) } } -func BenchmarkRemoveSafe(b *testing.B) { - benchRemove(b, NewSet[int]()) -} - -func BenchmarkRemoveUnsafe(b *testing.B) { - benchRemove(b, NewThreadUnsafeSet[int]()) -} +func BenchmarkRemove(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + nums := s.ToSlice() -func benchCardinality(b *testing.B, s Set[int]) { - for i := 0; i < b.N; i++ { - s.Cardinality() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + n := rand.Intn(c.n) + s.Clone().Remove(nums[n]) + } + }) } } -func BenchmarkCardinalitySafe(b *testing.B) { - benchCardinality(b, NewSet[int]()) -} - -func BenchmarkCardinalityUnsafe(b *testing.B) { - benchCardinality(b, NewThreadUnsafeSet[int]()) -} +func BenchmarkRemoveAll(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + nums := s.ToSlice() -func benchClear(b *testing.B, s Set[int]) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Clear() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + n := rand.Intn(c.n) + s.Clone().RemoveAll(nums[:n]...) + } + }) } } -func BenchmarkClearSafe(b *testing.B) { - benchClear(b, NewSet[int]()) -} - -func BenchmarkClearUnsafe(b *testing.B) { - benchClear(b, NewThreadUnsafeSet[int]()) -} - -func benchClone(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } +func BenchmarkCardinality(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Clone() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Cardinality() + } + }) } } -func BenchmarkClone1Safe(b *testing.B) { - benchClone(b, 1, NewSet[int]()) -} - -func BenchmarkClone1Unsafe(b *testing.B) { - benchClone(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkClone10Safe(b *testing.B) { - benchClone(b, 10, NewSet[int]()) -} - -func BenchmarkClone10Unsafe(b *testing.B) { - benchClone(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkClone100Safe(b *testing.B) { - benchClone(b, 100, NewSet[int]()) -} - -func BenchmarkClone100Unsafe(b *testing.B) { - benchClone(b, 100, NewThreadUnsafeSet[int]()) -} - -func benchContains(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } - - nums[n-1] = -1 // Definitely not in s +func BenchmarkClear(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Contains(nums...) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + s.Clone().Clear() + } + }) } } -func BenchmarkContains1Safe(b *testing.B) { - benchContains(b, 1, NewSet[int]()) -} - -func BenchmarkContains1Unsafe(b *testing.B) { - benchContains(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContains10Safe(b *testing.B) { - benchContains(b, 10, NewSet[int]()) -} - -func BenchmarkContains10Unsafe(b *testing.B) { - benchContains(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContains100Safe(b *testing.B) { - benchContains(b, 100, NewSet[int]()) -} - -func BenchmarkContains100Unsafe(b *testing.B) { - benchContains(b, 100, NewThreadUnsafeSet[int]()) -} - -func benchContainsOne(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } +func BenchmarkClone(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.ContainsOne(-1) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Clone() + } + }) } } -func BenchmarkContainsOne1Safe(b *testing.B) { - benchContainsOne(b, 1, NewSet[int]()) -} - -func BenchmarkContainsOne1Unsafe(b *testing.B) { - benchContainsOne(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContainsOne10Safe(b *testing.B) { - benchContainsOne(b, 10, NewSet[int]()) -} - -func BenchmarkContainsOne10Unsafe(b *testing.B) { - benchContainsOne(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContainsOne100Safe(b *testing.B) { - benchContainsOne(b, 100, NewSet[int]()) -} - -func BenchmarkContainsOne100Unsafe(b *testing.B) { - benchContainsOne(b, 100, NewThreadUnsafeSet[int]()) -} - -// In this scenario, Contains argument escapes to the heap, while ContainsOne does not. -func benchContainsComparison(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } +func BenchmarkContainsOne(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + nums := s.ToSlice() - b.Run("Contains", func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - for _, v := range nums { - s.Contains(v) // 1 allocation, v is moved to the heap - } - } - }) - b.Run("Contains slice", func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - for i := range nums { - s.Contains(nums[i : i+1]...) // no allocations, using heap-allocated slice - } - } - }) - b.Run("ContainsOne", func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - for _, v := range nums { - s.ContainsOne(v) // no allocations, using stack-allocated v + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + n := rand.Intn(c.n) + _ = s.ContainsOne(nums[n]) // no allocations, using stack-allocated v } - } - }) -} - -func BenchmarkContainsComparison1Unsafe(b *testing.B) { - benchContainsComparison(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContainsComparison1Safe(b *testing.B) { - benchContainsComparison(b, 1, NewSet[int]()) -} - -func BenchmarkContainsComparison10Unsafe(b *testing.B) { - benchContainsComparison(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContainsComparison10Safe(b *testing.B) { - benchContainsComparison(b, 10, NewSet[int]()) -} - -func BenchmarkContainsComparison100Unsafe(b *testing.B) { - benchContainsComparison(b, 100, NewThreadUnsafeSet[int]()) -} - -func BenchmarkContainsComparison100Safe(b *testing.B) { - benchContainsComparison(b, 100, NewSet[int]()) -} - -func benchEqual(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - t.Add(v) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Equal(t) + }) } } -func BenchmarkEqual1Safe(b *testing.B) { - benchEqual(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkEqual1Unsafe(b *testing.B) { - benchEqual(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkEqual10Safe(b *testing.B) { - benchEqual(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkEqual10Unsafe(b *testing.B) { - benchEqual(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkEqual100Safe(b *testing.B) { - benchEqual(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkEqual100Unsafe(b *testing.B) { - benchEqual(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchDifference(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } - for _, v := range nums[:n/2] { - t.Add(v) - } +func BenchmarkContains(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + nums := s.ToSlice() - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Difference(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + n := rand.Intn(c.n) + _ = s.Contains(nums[:n]...) // no allocations, using heap-allocated slice + } + }) } } -func benchIsSubset(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - t.Add(v) - } +func BenchmarkContainsAny(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + nums := s.ToSlice() - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.IsSubset(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + n := rand.Intn(c.n) + _ = s.ContainsAny(nums[:n]...) // no allocations, using heap-allocated slice + } + }) } } -func BenchmarkIsSubset1Safe(b *testing.B) { - benchIsSubset(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSubset1Unsafe(b *testing.B) { - benchIsSubset(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsSubset10Safe(b *testing.B) { - benchIsSubset(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSubset10Unsafe(b *testing.B) { - benchIsSubset(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsSubset100Safe(b *testing.B) { - benchIsSubset(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSubset100Unsafe(b *testing.B) { - benchIsSubset(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchIsSuperset(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - t.Add(v) - } +func BenchmarkEqual(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.IsSuperset(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Equal(t) + } + }) } } -func BenchmarkIsSuperset1Safe(b *testing.B) { - benchIsSuperset(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSuperset1Unsafe(b *testing.B) { - benchIsSuperset(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsSuperset10Safe(b *testing.B) { - benchIsSuperset(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSuperset10Unsafe(b *testing.B) { - benchIsSuperset(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsSuperset100Safe(b *testing.B) { - benchIsSuperset(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsSuperset100Unsafe(b *testing.B) { - benchIsSuperset(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchIsProperSubset(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - t.Add(v) - } +func BenchmarkIsSubset(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.IsProperSubset(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.IsSubset(t) + } + }) } } -func BenchmarkIsProperSubset1Safe(b *testing.B) { - benchIsProperSubset(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSubset1Unsafe(b *testing.B) { - benchIsProperSubset(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsProperSubset10Safe(b *testing.B) { - benchIsProperSubset(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSubset10Unsafe(b *testing.B) { - benchIsProperSubset(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsProperSubset100Safe(b *testing.B) { - benchIsProperSubset(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSubset100Unsafe(b *testing.B) { - benchIsProperSubset(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchIsProperSuperset(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - t.Add(v) - } +func BenchmarkIsSuperset(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.IsProperSuperset(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.IsSuperset(t) + } + }) } } -func BenchmarkIsProperSuperset1Safe(b *testing.B) { - benchIsProperSuperset(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSuperset1Unsafe(b *testing.B) { - benchIsProperSuperset(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsProperSuperset10Safe(b *testing.B) { - benchIsProperSuperset(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSuperset10Unsafe(b *testing.B) { - benchIsProperSuperset(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIsProperSuperset100Safe(b *testing.B) { - benchIsProperSuperset(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIsProperSuperset100Unsafe(b *testing.B) { - benchIsProperSuperset(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkDifference1Safe(b *testing.B) { - benchDifference(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkDifference1Unsafe(b *testing.B) { - benchDifference(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkDifference10Safe(b *testing.B) { - benchDifference(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkDifference10Unsafe(b *testing.B) { - benchDifference(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkDifference100Safe(b *testing.B) { - benchDifference(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkDifference100Unsafe(b *testing.B) { - benchDifference(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchIntersect(b *testing.B, n int, s, t Set[int]) { - nums := nrand(int(float64(n) * float64(1.5))) - for _, v := range nums[:n] { - s.Add(v) - } - for _, v := range nums[n/2:] { - t.Add(v) - } +func BenchmarkIsProperSubset(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Intersect(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.IsProperSubset(t) + } + }) } } -func BenchmarkIntersect1Safe(b *testing.B) { - benchIntersect(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIntersect1Unsafe(b *testing.B) { - benchIntersect(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIntersect10Safe(b *testing.B) { - benchIntersect(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIntersect10Unsafe(b *testing.B) { - benchIntersect(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkIntersect100Safe(b *testing.B) { - benchIntersect(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkIntersect100Unsafe(b *testing.B) { - benchIntersect(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchSymmetricDifference(b *testing.B, n int, s, t Set[int]) { - nums := nrand(int(float64(n) * float64(1.5))) - for _, v := range nums[:n] { - s.Add(v) - } - for _, v := range nums[n/2:] { - t.Add(v) - } +func BenchmarkIsProperSuperset(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.SymmetricDifference(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.IsProperSuperset(t) + } + }) } } -func BenchmarkSymmetricDifference1Safe(b *testing.B) { - benchSymmetricDifference(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkSymmetricDifference1Unsafe(b *testing.B) { - benchSymmetricDifference(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkSymmetricDifference10Safe(b *testing.B) { - benchSymmetricDifference(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkSymmetricDifference10Unsafe(b *testing.B) { - benchSymmetricDifference(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkSymmetricDifference100Safe(b *testing.B) { - benchSymmetricDifference(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkSymmetricDifference100Unsafe(b *testing.B) { - benchSymmetricDifference(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchUnion(b *testing.B, n int, s, t Set[int]) { - nums := nrand(n) - for _, v := range nums[:n/2] { - s.Add(v) - } - for _, v := range nums[n/2:] { - t.Add(v) - } +func BenchmarkDifference(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Union(t) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Difference(t) + } + }) } } -func BenchmarkUnion1Safe(b *testing.B) { - benchUnion(b, 1, NewSet[int](), NewSet[int]()) -} - -func BenchmarkUnion1Unsafe(b *testing.B) { - benchUnion(b, 1, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkUnion10Safe(b *testing.B) { - benchUnion(b, 10, NewSet[int](), NewSet[int]()) -} - -func BenchmarkUnion10Unsafe(b *testing.B) { - benchUnion(b, 10, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func BenchmarkUnion100Safe(b *testing.B) { - benchUnion(b, 100, NewSet[int](), NewSet[int]()) -} - -func BenchmarkUnion100Unsafe(b *testing.B) { - benchUnion(b, 100, NewThreadUnsafeSet[int](), NewThreadUnsafeSet[int]()) -} - -func benchEach(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } +func BenchmarkIntersect(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.Each(func(elem int) bool { - return false + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Intersect(t) + } }) } } -func BenchmarkEach1Safe(b *testing.B) { - benchEach(b, 1, NewSet[int]()) -} - -func BenchmarkEach1Unsafe(b *testing.B) { - benchEach(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkEach10Safe(b *testing.B) { - benchEach(b, 10, NewSet[int]()) -} - -func BenchmarkEach10Unsafe(b *testing.B) { - benchEach(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkEach100Safe(b *testing.B) { - benchEach(b, 100, NewSet[int]()) -} - -func BenchmarkEach100Unsafe(b *testing.B) { - benchEach(b, 100, NewThreadUnsafeSet[int]()) -} - -func benchIter(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - c := s.Iter() - for range c { +func BenchmarkSymmetricDifference(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - } + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.SymmetricDifference(t) + } + }) } } -func BenchmarkIter1Safe(b *testing.B) { - benchIter(b, 1, NewSet[int]()) -} - -func BenchmarkIter1Unsafe(b *testing.B) { - benchIter(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkIter10Safe(b *testing.B) { - benchIter(b, 10, NewSet[int]()) -} - -func BenchmarkIter10Unsafe(b *testing.B) { - benchIter(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkIter100Safe(b *testing.B) { - benchIter(b, 100, NewSet[int]()) -} - -func BenchmarkIter100Unsafe(b *testing.B) { - benchIter(b, 100, NewThreadUnsafeSet[int]()) -} - -func benchIterator(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - c := s.Iterator().C - for range c { +func BenchmarkUnion(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) + t := buildRandomSet(c.n, c.safe) - } + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.Union(t) + } + }) } } -func BenchmarkIterator1Safe(b *testing.B) { - benchIterator(b, 1, NewSet[int]()) -} - -func BenchmarkIterator1Unsafe(b *testing.B) { - benchIterator(b, 1, NewThreadUnsafeSet[int]()) -} - -func BenchmarkIterator10Safe(b *testing.B) { - benchIterator(b, 10, NewSet[int]()) -} - -func BenchmarkIterator10Unsafe(b *testing.B) { - benchIterator(b, 10, NewThreadUnsafeSet[int]()) -} - -func BenchmarkIterator100Safe(b *testing.B) { - benchIterator(b, 100, NewSet[int]()) -} - -func BenchmarkIterator100Unsafe(b *testing.B) { - benchIterator(b, 100, NewThreadUnsafeSet[int]()) -} - -func benchString(b *testing.B, n int, s Set[int]) { - nums := nrand(n) - for _, v := range nums { - s.Add(v) - } +func BenchmarkEach(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = s.String() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + s.Each(func(e int) bool { + _ = e + return false + }) + } + }) } } -func BenchmarkString1Safe(b *testing.B) { - benchString(b, 1, NewSet[int]()) -} +func BenchmarkIter(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) -func BenchmarkString1Unsafe(b *testing.B) { - benchString(b, 1, NewThreadUnsafeSet[int]()) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + for e := range s.Iter() { + _ = e + } + } + }) + } } -func BenchmarkString10Safe(b *testing.B) { - benchString(b, 10, NewSet[int]()) -} +func BenchmarkIterator(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) -func BenchmarkString10Unsafe(b *testing.B) { - benchString(b, 10, NewThreadUnsafeSet[int]()) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + for e := range s.Iterator().C { + _ = e + } + } + }) + } } -func BenchmarkString100Safe(b *testing.B) { - benchString(b, 100, NewSet[int]()) -} +func BenchmarkString(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) -func BenchmarkString100Unsafe(b *testing.B) { - benchString(b, 100, NewThreadUnsafeSet[int]()) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.String() + } + }) + } } -func benchToSlice(b *testing.B, s Set[int]) { - nums := nrand(b.N) - for _, v := range nums { - s.Add(v) - } +func BenchmarkToSlice(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) - b.ResetTimer() - for i := 0; i < b.N; i++ { - s.ToSlice() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = s.ToSlice() + } + }) } } -func BenchmarkToSliceSafe(b *testing.B) { - benchToSlice(b, NewSet[int]()) -} +func BenchmarkMarshalJSON(b *testing.B) { + for _, c := range buildBenchCases(1, 10, 100) { + s := buildRandomSet(c.n, c.safe) -func BenchmarkToSliceUnsafe(b *testing.B) { - benchToSlice(b, NewThreadUnsafeSet[int]()) + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = s.MarshalJSON() + } + }) + } } -func BenchmarkMarshalJSON(b *testing.B) { +func BenchmarkUnmarshalJSON(b *testing.B) { for _, c := range buildBenchCases(1, 10, 100) { s := buildRandomSet(c.n, c.safe) + json, _ := s.MarshalJSON() + b.Run(buildCaseName(c.n, c.safe), func(b *testing.B) { for i := 0; i < b.N; i++ { - _, _ = s.MarshalJSON() + _ = s.UnmarshalJSON(json) } }) }