1
1
use std:: collections:: BTreeSet ;
2
+ use std:: collections:: btree_set:: Intersection ;
2
3
3
4
use rand:: { thread_rng, Rng } ;
4
5
use test:: { black_box, Bencher } ;
5
6
6
- fn random ( n1 : u32 , n2 : u32 ) -> [ BTreeSet < usize > ; 2 ] {
7
+ fn random ( n1 : usize , n2 : usize ) -> [ BTreeSet < usize > ; 2 ] {
7
8
let mut rng = thread_rng ( ) ;
8
- let mut set1 = BTreeSet :: new ( ) ;
9
- let mut set2 = BTreeSet :: new ( ) ;
10
- for _ in 0 ..n1 {
11
- let i = rng. gen :: < usize > ( ) ;
12
- set1. insert ( i) ;
13
- }
14
- for _ in 0 ..n2 {
15
- let i = rng. gen :: < usize > ( ) ;
16
- set2. insert ( i) ;
9
+ let mut sets = [ BTreeSet :: new ( ) , BTreeSet :: new ( ) ] ;
10
+ for i in 0 ..2 {
11
+ while sets[ i] . len ( ) < [ n1, n2] [ i] {
12
+ sets[ i] . insert ( rng. gen ( ) ) ;
13
+ }
17
14
}
18
- [ set1, set2]
15
+ assert_eq ! ( sets[ 0 ] . len( ) , n1) ;
16
+ assert_eq ! ( sets[ 1 ] . len( ) , n2) ;
17
+ sets
19
18
}
20
19
21
- fn staggered ( n1 : u32 , n2 : u32 ) -> [ BTreeSet < u32 > ; 2 ] {
22
- let mut even = BTreeSet :: new ( ) ;
23
- let mut odd = BTreeSet :: new ( ) ;
24
- for i in 0 ..n1 {
25
- even. insert ( i * 2 ) ;
26
- }
27
- for i in 0 ..n2 {
28
- odd. insert ( i * 2 + 1 ) ;
20
+ fn stagger ( n1 : usize , factor : usize ) -> [ BTreeSet < u32 > ; 2 ] {
21
+ let n2 = n1 * factor;
22
+ let mut sets = [ BTreeSet :: new ( ) , BTreeSet :: new ( ) ] ;
23
+ for i in 0 ..( n1 + n2) {
24
+ let b = i % ( factor + 1 ) != 0 ;
25
+ sets[ b as usize ] . insert ( i as u32 ) ;
29
26
}
30
- [ even, odd]
27
+ assert_eq ! ( sets[ 0 ] . len( ) , n1) ;
28
+ assert_eq ! ( sets[ 1 ] . len( ) , n2) ;
29
+ sets
31
30
}
32
31
33
- fn neg_vs_pos ( n1 : u32 , n2 : u32 ) -> [ BTreeSet < i32 > ; 2 ] {
32
+ fn neg_vs_pos ( n1 : usize , n2 : usize ) -> [ BTreeSet < i32 > ; 2 ] {
34
33
let mut neg = BTreeSet :: new ( ) ;
35
34
let mut pos = BTreeSet :: new ( ) ;
36
35
for i in -( n1 as i32 ) ..=-1 {
@@ -39,22 +38,38 @@ fn neg_vs_pos(n1: u32, n2: u32) -> [BTreeSet<i32>; 2] {
39
38
for i in 1 ..=( n2 as i32 ) {
40
39
pos. insert ( i) ;
41
40
}
41
+ assert_eq ! ( neg. len( ) , n1) ;
42
+ assert_eq ! ( pos. len( ) , n2) ;
42
43
[ neg, pos]
43
44
}
44
45
45
- fn pos_vs_neg ( n1 : u32 , n2 : u32 ) -> [ BTreeSet < i32 > ; 2 ] {
46
- let mut neg = BTreeSet :: new ( ) ;
47
- let mut pos = BTreeSet :: new ( ) ;
48
- for i in -( n1 as i32 ) ..=-1 {
49
- neg. insert ( i) ;
46
+ fn pos_vs_neg ( n1 : usize , n2 : usize ) -> [ BTreeSet < i32 > ; 2 ] {
47
+ let mut sets = neg_vs_pos ( n2, n1) ;
48
+ sets. reverse ( ) ;
49
+ assert_eq ! ( sets[ 0 ] . len( ) , n1) ;
50
+ assert_eq ! ( sets[ 1 ] . len( ) , n2) ;
51
+ sets
52
+ }
53
+
54
+ fn intersection_search < T > ( sets : & [ BTreeSet < T > ; 2 ] ) -> Intersection < T >
55
+ where T : std:: cmp:: Ord
56
+ {
57
+ Intersection :: Search {
58
+ a_iter : sets[ 0 ] . iter ( ) ,
59
+ b_set : & sets[ 1 ] ,
50
60
}
51
- for i in 1 ..=( n2 as i32 ) {
52
- pos. insert ( i) ;
61
+ }
62
+
63
+ fn intersection_stitch < T > ( sets : & [ BTreeSet < T > ; 2 ] ) -> Intersection < T >
64
+ where T : std:: cmp:: Ord
65
+ {
66
+ Intersection :: Stitch {
67
+ a_iter : sets[ 0 ] . iter ( ) ,
68
+ b_iter : sets[ 1 ] . iter ( ) ,
53
69
}
54
- [ pos, neg]
55
70
}
56
71
57
- macro_rules! set_intersection_bench {
72
+ macro_rules! intersection_bench {
58
73
( $name: ident, $sets: expr) => {
59
74
#[ bench]
60
75
pub fn $name( b: & mut Bencher ) {
@@ -68,21 +83,64 @@ macro_rules! set_intersection_bench {
68
83
} )
69
84
}
70
85
} ;
86
+ ( $name: ident, $sets: expr, $intersection_kind: ident) => {
87
+ #[ bench]
88
+ pub fn $name( b: & mut Bencher ) {
89
+ // setup
90
+ let sets = $sets;
91
+ assert!( sets[ 0 ] . len( ) >= 1 ) ;
92
+ assert!( sets[ 1 ] . len( ) >= sets[ 0 ] . len( ) ) ;
93
+
94
+ // measure
95
+ b. iter( || {
96
+ let x = $intersection_kind( & sets) . count( ) ;
97
+ black_box( x) ;
98
+ } )
99
+ }
100
+ } ;
71
101
}
72
102
73
- set_intersection_bench ! { intersect_random_100, random( 100 , 100 ) }
74
- set_intersection_bench ! { intersect_random_10k, random( 10_000 , 10_000 ) }
75
- set_intersection_bench ! { intersect_random_10_vs_10k, random( 10 , 10_000 ) }
76
- set_intersection_bench ! { intersect_random_10k_vs_10, random( 10_000 , 10 ) }
77
- set_intersection_bench ! { intersect_staggered_100, staggered( 100 , 100 ) }
78
- set_intersection_bench ! { intersect_staggered_10k, staggered( 10_000 , 10_000 ) }
79
- set_intersection_bench ! { intersect_staggered_10_vs_10k, staggered( 10 , 10_000 ) }
80
- set_intersection_bench ! { intersect_staggered_10k_vs_10, staggered( 10_000 , 10 ) }
81
- set_intersection_bench ! { intersect_neg_vs_pos_100, neg_vs_pos( 100 , 100 ) }
82
- set_intersection_bench ! { intersect_neg_vs_pos_10k, neg_vs_pos( 10_000 , 10_000 ) }
83
- set_intersection_bench ! { intersect_neg_vs_pos_10_vs_10k, neg_vs_pos( 10 , 10_000 ) }
84
- set_intersection_bench ! { intersect_neg_vs_pos_10k_vs_10, neg_vs_pos( 10_000 , 10 ) }
85
- set_intersection_bench ! { intersect_pos_vs_neg_100, pos_vs_neg( 100 , 100 ) }
86
- set_intersection_bench ! { intersect_pos_vs_neg_10k, pos_vs_neg( 10_000 , 10_000 ) }
87
- set_intersection_bench ! { intersect_pos_vs_neg_10_vs_10k, pos_vs_neg( 10 , 10_000 ) }
88
- set_intersection_bench ! { intersect_pos_vs_neg_10k_vs_10, pos_vs_neg( 10_000 , 10 ) }
103
+ intersection_bench ! { intersect_100_neg_vs_100_pos, neg_vs_pos( 100 , 100 ) }
104
+ intersection_bench ! { intersect_100_neg_vs_10k_pos, neg_vs_pos( 100 , 10_000 ) }
105
+ intersection_bench ! { intersect_100_pos_vs_100_neg, pos_vs_neg( 100 , 100 ) }
106
+ intersection_bench ! { intersect_100_pos_vs_10k_neg, pos_vs_neg( 100 , 10_000 ) }
107
+ intersection_bench ! { intersect_10k_neg_vs_100_pos, neg_vs_pos( 10_000 , 100 ) }
108
+ intersection_bench ! { intersect_10k_neg_vs_10k_pos, neg_vs_pos( 10_000 , 10_000 ) }
109
+ intersection_bench ! { intersect_10k_pos_vs_100_neg, pos_vs_neg( 10_000 , 100 ) }
110
+ intersection_bench ! { intersect_10k_pos_vs_10k_neg, pos_vs_neg( 10_000 , 10_000 ) }
111
+ intersection_bench ! { intersect_random_100_vs_100_actual, random( 100 , 100 ) }
112
+ intersection_bench ! { intersect_random_100_vs_100_search, random( 100 , 100 ) , intersection_search}
113
+ intersection_bench ! { intersect_random_100_vs_100_stitch, random( 100 , 100 ) , intersection_stitch}
114
+ intersection_bench ! { intersect_random_100_vs_10k_actual, random( 100 , 10_000 ) }
115
+ intersection_bench ! { intersect_random_100_vs_10k_search, random( 100 , 10_000 ) , intersection_search}
116
+ intersection_bench ! { intersect_random_100_vs_10k_stitch, random( 100 , 10_000 ) , intersection_stitch}
117
+ intersection_bench ! { intersect_random_10k_vs_10k_actual, random( 10_000 , 10_000 ) }
118
+ intersection_bench ! { intersect_random_10k_vs_10k_search, random( 10_000 , 10_000 ) , intersection_search}
119
+ intersection_bench ! { intersect_random_10k_vs_10k_stitch, random( 10_000 , 10_000 ) , intersection_stitch}
120
+ intersection_bench ! { intersect_stagger_100_actual, stagger( 100 , 1 ) }
121
+ intersection_bench ! { intersect_stagger_100_search, stagger( 100 , 1 ) , intersection_search}
122
+ intersection_bench ! { intersect_stagger_100_stitch, stagger( 100 , 1 ) , intersection_stitch}
123
+ intersection_bench ! { intersect_stagger_10k_actual, stagger( 10_000 , 1 ) }
124
+ intersection_bench ! { intersect_stagger_10k_search, stagger( 10_000 , 1 ) , intersection_search}
125
+ intersection_bench ! { intersect_stagger_10k_stitch, stagger( 10_000 , 1 ) , intersection_stitch}
126
+ intersection_bench ! { intersect_stagger_1_actual, stagger( 1 , 1 ) }
127
+ intersection_bench ! { intersect_stagger_1_search, stagger( 1 , 1 ) , intersection_search}
128
+ intersection_bench ! { intersect_stagger_1_stitch, stagger( 1 , 1 ) , intersection_stitch}
129
+ intersection_bench ! { intersect_stagger_diff1_actual, stagger( 100 , 1 << 1 ) }
130
+ intersection_bench ! { intersect_stagger_diff1_search, stagger( 100 , 1 << 1 ) , intersection_search}
131
+ intersection_bench ! { intersect_stagger_diff1_stitch, stagger( 100 , 1 << 1 ) , intersection_stitch}
132
+ intersection_bench ! { intersect_stagger_diff2_actual, stagger( 100 , 1 << 2 ) }
133
+ intersection_bench ! { intersect_stagger_diff2_search, stagger( 100 , 1 << 2 ) , intersection_search}
134
+ intersection_bench ! { intersect_stagger_diff2_stitch, stagger( 100 , 1 << 2 ) , intersection_stitch}
135
+ intersection_bench ! { intersect_stagger_diff3_actual, stagger( 100 , 1 << 3 ) }
136
+ intersection_bench ! { intersect_stagger_diff3_search, stagger( 100 , 1 << 3 ) , intersection_search}
137
+ intersection_bench ! { intersect_stagger_diff3_stitch, stagger( 100 , 1 << 3 ) , intersection_stitch}
138
+ intersection_bench ! { intersect_stagger_diff4_actual, stagger( 100 , 1 << 4 ) }
139
+ intersection_bench ! { intersect_stagger_diff4_search, stagger( 100 , 1 << 4 ) , intersection_search}
140
+ intersection_bench ! { intersect_stagger_diff4_stitch, stagger( 100 , 1 << 4 ) , intersection_stitch}
141
+ intersection_bench ! { intersect_stagger_diff5_actual, stagger( 100 , 1 << 5 ) }
142
+ intersection_bench ! { intersect_stagger_diff5_search, stagger( 100 , 1 << 5 ) , intersection_search}
143
+ intersection_bench ! { intersect_stagger_diff5_stitch, stagger( 100 , 1 << 5 ) , intersection_stitch}
144
+ intersection_bench ! { intersect_stagger_diff6_actual, stagger( 100 , 1 << 6 ) }
145
+ intersection_bench ! { intersect_stagger_diff6_search, stagger( 100 , 1 << 6 ) , intersection_search}
146
+ intersection_bench ! { intersect_stagger_diff6_stitch, stagger( 100 , 1 << 6 ) , intersection_stitch}
0 commit comments