@@ -8,7 +8,34 @@ use core::{
88} ;
99use std:: collections:: HashMap ;
1010
11- use criterion:: { BenchmarkId , Criterion , criterion_group, criterion_main} ;
11+ use criterion:: { BatchSize , BenchmarkId , Criterion , Throughput , criterion_group, criterion_main} ;
12+
13+ const COLLECTION_KEYS : usize = 4096 ;
14+
15+ fn collection_key ( index : u64 ) -> [ u8 ; 32 ] {
16+ let mut state = index;
17+ let mut key = [ 0u8 ; 32 ] ;
18+ for lane in key. chunks_exact_mut ( 8 ) {
19+ state = state. wrapping_add ( 0x9e37_79b9_7f4a_7c15 ) ;
20+ let mut word = state;
21+ word = ( word ^ ( word >> 30 ) ) . wrapping_mul ( 0xbf58_476d_1ce4_e5b9 ) ;
22+ word = ( word ^ ( word >> 27 ) ) . wrapping_mul ( 0x94d0_49bb_1331_11eb ) ;
23+ lane. copy_from_slice ( & ( word ^ ( word >> 31 ) ) . to_le_bytes ( ) ) ;
24+ }
25+ key
26+ }
27+
28+ fn collection_keys ( start : u64 ) -> Vec < [ u8 ; 32 ] > {
29+ ( 0 ..COLLECTION_KEYS )
30+ . map ( |index| collection_key ( start. wrapping_add ( index as u64 ) ) )
31+ . collect ( )
32+ }
33+
34+ fn populated_map < S : BuildHasher > ( keys : & [ [ u8 ; 32 ] ] , state : S ) -> HashMap < [ u8 ; 32 ] , usize , S > {
35+ let mut map = HashMap :: with_capacity_and_hasher ( keys. len ( ) , state) ;
36+ map. extend ( keys. iter ( ) . copied ( ) . enumerate ( ) . map ( |( value, key) | ( key, value) ) ) ;
37+ map
38+ }
1239
1340fn rapidhash_v3_64 ( c : & mut Criterion ) {
1441 let inputs = common:: comp_sizes ( ) ;
@@ -48,21 +75,110 @@ fn rapidhash_seeded_state(c: &mut Criterion) {
4875 group. finish ( ) ;
4976}
5077
51- fn rapidhash_hashmap_lookup ( c : & mut Criterion ) {
52- let key = common:: random_bytes ( 32 ) ;
53- let mut ours = HashMap :: with_capacity_and_hasher ( 1 , rscrypto:: RapidSeededState :: new ( 0 ) ) ;
54- let mut upstream = HashMap :: with_capacity_and_hasher ( 1 , rapidhash:: quality:: SeedableState :: fixed ( ) ) ;
55- ours. insert ( key. as_slice ( ) , 1u8 ) ;
56- upstream. insert ( key. as_slice ( ) , 1u8 ) ;
78+ fn rapidhash_key_types ( c : & mut Criterion ) {
79+ let ours = rscrypto:: RapidSeededState :: new ( 0 ) ;
80+ let upstream = rapidhash:: quality:: SeedableState :: fixed ( ) ;
81+ let integer = 0xa5c3_17e9_6b4d_2f01u64 ;
82+ let bytes = collection_key ( 17 ) ;
83+ let text = "collection-key" ;
84+
85+ let mut integer_group = c. benchmark_group ( "rapidhash-hash-one/u64" ) ;
86+ integer_group. bench_function ( "rscrypto" , |b| b. iter ( || black_box ( ours. hash_one ( black_box ( integer) ) ) ) ) ;
87+ integer_group. bench_function ( "rapidhash" , |b| {
88+ b. iter ( || black_box ( upstream. hash_one ( black_box ( integer) ) ) )
89+ } ) ;
90+ integer_group. finish ( ) ;
5791
58- let mut group = c. benchmark_group ( "rapidhash-hashmap/lookup-32" ) ;
59- group. bench_function ( "rscrypto" , |b| {
60- b. iter ( || black_box ( ours. get ( black_box ( key. as_slice ( ) ) ) ) )
92+ let mut bytes_group = c. benchmark_group ( "rapidhash-hash-one/array-32" ) ;
93+ bytes_group. bench_function ( "rscrypto" , |b| b. iter ( || black_box ( ours. hash_one ( black_box ( bytes) ) ) ) ) ;
94+ bytes_group. bench_function ( "rapidhash" , |b| {
95+ b. iter ( || black_box ( upstream. hash_one ( black_box ( bytes) ) ) )
6196 } ) ;
62- group. bench_function ( "rapidhash" , |b| {
63- b. iter ( || black_box ( upstream. get ( black_box ( key. as_slice ( ) ) ) ) )
97+ bytes_group. finish ( ) ;
98+
99+ let mut text_group = c. benchmark_group ( "rapidhash-hash-one/str-14" ) ;
100+ text_group. bench_function ( "rscrypto" , |b| b. iter ( || black_box ( ours. hash_one ( black_box ( text) ) ) ) ) ;
101+ text_group. bench_function ( "rapidhash" , |b| {
102+ b. iter ( || black_box ( upstream. hash_one ( black_box ( text) ) ) )
64103 } ) ;
65- group. finish ( ) ;
104+ text_group. finish ( ) ;
105+ }
106+
107+ fn rapidhash_hashmap_operations ( c : & mut Criterion ) {
108+ let present = collection_keys ( 0 ) ;
109+ let absent = collection_keys ( COLLECTION_KEYS as u64 ) ;
110+ let ours = populated_map ( & present, rscrypto:: RapidSeededState :: new ( 0 ) ) ;
111+ let upstream = populated_map ( & present, rapidhash:: quality:: SeedableState :: fixed ( ) ) ;
112+
113+ let mut insert = c. benchmark_group ( "rapidhash-hashmap/insert-32" ) ;
114+ insert. throughput ( Throughput :: Elements ( COLLECTION_KEYS as u64 ) ) ;
115+ insert. bench_function ( "rscrypto" , |b| {
116+ b. iter_batched_ref (
117+ || HashMap :: with_capacity_and_hasher ( COLLECTION_KEYS , rscrypto:: RapidSeededState :: new ( 0 ) ) ,
118+ |map| {
119+ for ( value, key) in black_box ( present. as_slice ( ) ) . iter ( ) . copied ( ) . enumerate ( ) {
120+ black_box ( map. insert ( key, value) ) ;
121+ }
122+ } ,
123+ BatchSize :: LargeInput ,
124+ )
125+ } ) ;
126+ insert. bench_function ( "rapidhash" , |b| {
127+ b. iter_batched_ref (
128+ || HashMap :: with_capacity_and_hasher ( COLLECTION_KEYS , rapidhash:: quality:: SeedableState :: fixed ( ) ) ,
129+ |map| {
130+ for ( value, key) in black_box ( present. as_slice ( ) ) . iter ( ) . copied ( ) . enumerate ( ) {
131+ black_box ( map. insert ( key, value) ) ;
132+ }
133+ } ,
134+ BatchSize :: LargeInput ,
135+ )
136+ } ) ;
137+ insert. finish ( ) ;
138+
139+ let mut hit = c. benchmark_group ( "rapidhash-hashmap/hit-32" ) ;
140+ hit. throughput ( Throughput :: Elements ( COLLECTION_KEYS as u64 ) ) ;
141+ hit. bench_function ( "rscrypto" , |b| {
142+ b. iter ( || {
143+ let mut found = 0usize ;
144+ for key in black_box ( present. as_slice ( ) ) {
145+ found = found. wrapping_add ( black_box ( ours. get ( black_box ( key) ) ) . is_some ( ) as usize ) ;
146+ }
147+ black_box ( found)
148+ } )
149+ } ) ;
150+ hit. bench_function ( "rapidhash" , |b| {
151+ b. iter ( || {
152+ let mut found = 0usize ;
153+ for key in black_box ( present. as_slice ( ) ) {
154+ found = found. wrapping_add ( black_box ( upstream. get ( black_box ( key) ) ) . is_some ( ) as usize ) ;
155+ }
156+ black_box ( found)
157+ } )
158+ } ) ;
159+ hit. finish ( ) ;
160+
161+ let mut miss = c. benchmark_group ( "rapidhash-hashmap/miss-32" ) ;
162+ miss. throughput ( Throughput :: Elements ( COLLECTION_KEYS as u64 ) ) ;
163+ miss. bench_function ( "rscrypto" , |b| {
164+ b. iter ( || {
165+ let mut found = 0usize ;
166+ for key in black_box ( absent. as_slice ( ) ) {
167+ found = found. wrapping_add ( black_box ( ours. get ( black_box ( key) ) ) . is_some ( ) as usize ) ;
168+ }
169+ black_box ( found)
170+ } )
171+ } ) ;
172+ miss. bench_function ( "rapidhash" , |b| {
173+ b. iter ( || {
174+ let mut found = 0usize ;
175+ for key in black_box ( absent. as_slice ( ) ) {
176+ found = found. wrapping_add ( black_box ( upstream. get ( black_box ( key) ) ) . is_some ( ) as usize ) ;
177+ }
178+ black_box ( found)
179+ } )
180+ } ) ;
181+ miss. finish ( ) ;
66182}
67183
68184fn rapidhash_streaming ( c : & mut Criterion ) {
@@ -113,7 +229,8 @@ criterion_group!(
113229 benches,
114230 rapidhash_v3_64,
115231 rapidhash_seeded_state,
116- rapidhash_hashmap_lookup,
232+ rapidhash_key_types,
233+ rapidhash_hashmap_operations,
117234 rapidhash_streaming
118235) ;
119236criterion_main ! ( benches) ;
0 commit comments