@@ -180,6 +180,99 @@ func BenchmarkContains100Unsafe(b *testing.B) {
180180 benchContains (b , 100 , NewThreadUnsafeSet [int ]())
181181}
182182
183+ func benchContainsOne (b * testing.B , n int , s Set [int ]) {
184+ nums := nrand (n )
185+ for _ , v := range nums {
186+ s .Add (v )
187+ }
188+
189+ b .ResetTimer ()
190+ for i := 0 ; i < b .N ; i ++ {
191+ s .ContainsOne (- 1 )
192+ }
193+ }
194+
195+ func BenchmarkContainsOne1Safe (b * testing.B ) {
196+ benchContainsOne (b , 1 , NewSet [int ]())
197+ }
198+
199+ func BenchmarkContainsOne1Unsafe (b * testing.B ) {
200+ benchContainsOne (b , 1 , NewThreadUnsafeSet [int ]())
201+ }
202+
203+ func BenchmarkContainsOne10Safe (b * testing.B ) {
204+ benchContainsOne (b , 10 , NewSet [int ]())
205+ }
206+
207+ func BenchmarkContainsOne10Unsafe (b * testing.B ) {
208+ benchContainsOne (b , 10 , NewThreadUnsafeSet [int ]())
209+ }
210+
211+ func BenchmarkContainsOne100Safe (b * testing.B ) {
212+ benchContainsOne (b , 100 , NewSet [int ]())
213+ }
214+
215+ func BenchmarkContainsOne100Unsafe (b * testing.B ) {
216+ benchContainsOne (b , 100 , NewThreadUnsafeSet [int ]())
217+ }
218+
219+ // In this scenario, Contains argument escapes to the heap, while ContainsOne does not.
220+ func benchContainsComparison (b * testing.B , n int , s Set [int ]) {
221+ nums := nrand (n )
222+ for _ , v := range nums {
223+ s .Add (v )
224+ }
225+
226+ b .Run ("Contains" , func (b * testing.B ) {
227+ b .ReportAllocs ()
228+ for i := 0 ; i < b .N ; i ++ {
229+ for _ , v := range nums {
230+ s .Contains (v ) // 1 allocation, v is moved to the heap
231+ }
232+ }
233+ })
234+ b .Run ("Contains slice" , func (b * testing.B ) {
235+ b .ReportAllocs ()
236+ for i := 0 ; i < b .N ; i ++ {
237+ for i := range nums {
238+ s .Contains (nums [i : i + 1 ]... ) // no allocations, using heap-allocated slice
239+ }
240+ }
241+ })
242+ b .Run ("ContainsOne" , func (b * testing.B ) {
243+ b .ReportAllocs ()
244+ for i := 0 ; i < b .N ; i ++ {
245+ for _ , v := range nums {
246+ s .ContainsOne (v ) // no allocations, using stack-allocated v
247+ }
248+ }
249+ })
250+ }
251+
252+ func BenchmarkContainsComparison1Unsafe (b * testing.B ) {
253+ benchContainsComparison (b , 1 , NewThreadUnsafeSet [int ]())
254+ }
255+
256+ func BenchmarkContainsComparison1Safe (b * testing.B ) {
257+ benchContainsComparison (b , 1 , NewSet [int ]())
258+ }
259+
260+ func BenchmarkContainsComparison10Unsafe (b * testing.B ) {
261+ benchContainsComparison (b , 10 , NewThreadUnsafeSet [int ]())
262+ }
263+
264+ func BenchmarkContainsComparison10Safe (b * testing.B ) {
265+ benchContainsComparison (b , 10 , NewSet [int ]())
266+ }
267+
268+ func BenchmarkContainsComparison100Unsafe (b * testing.B ) {
269+ benchContainsComparison (b , 100 , NewThreadUnsafeSet [int ]())
270+ }
271+
272+ func BenchmarkContainsComparison100Safe (b * testing.B ) {
273+ benchContainsComparison (b , 100 , NewSet [int ]())
274+ }
275+
183276func benchEqual (b * testing.B , n int , s , t Set [int ]) {
184277 nums := nrand (n )
185278 for _ , v := range nums {
0 commit comments