1 use std::hash::{Hash, Hasher};
2
3 use criterion::*;
4 use fxhash::FxHasher;
5
6 use ahash::{AHasher, CallHasher};
7
gen_word_pairs() -> Vec<String>8 fn gen_word_pairs() -> Vec<String> {
9 let words: Vec<_> = r#"
10 a, ability, able, about, above, accept, according, account, across, act, action,
11 activity, actually, add, address, administration, admit, adult, affect, after,
12 again, against, age, agency, agent, ago, agree, agreement, ahead, air, all,
13 allow, almost, alone, along, already, also, although, always, American, among,
14 amount, analysis, and, animal, another, answer, any, anyone, anything, appear,
15 apply, approach, area, argue, arm, around, arrive, art, article, artist, as,
16 ask, assume, at, attack, attention, attorney, audience, author, authority,
17 available, avoid, away, baby, back, bad, bag, ball, bank, bar, base, be, beat,
18 beautiful, because, become, bed, before, begin, behavior, behind, believe,
19 benefit, best, better, between, beyond, big, bill, billion, bit, black, blood,
20 blue, board, body, book, born, both, box, boy, break, bring, brother, budget,
21 build, building, business, but, buy, by, call, camera, campaign, can, cancer,
22 candidate, capital, car, card, care, career, carry, case, catch, cause, cell,
23 center, central, century, certain, certainly, chair, challenge, chance, change,
24 character, charge, check, child, choice, choose, church, citizen, city, civil,
25 claim, class, clear, clearly, close, coach, cold, collection, college, color,
26 come, commercial, common, community, company, compare, computer, concern,
27 condition, conference, Congress, consider, consumer, contain, continue, control,
28 cost, could, country, couple, course, court, cover, create, crime, cultural,
29 culture, cup, current, customer, cut, dark, data, daughter, day, dead, deal,
30 death, debate, decade, decide, decision, deep, defense, degree, Democrat,
31 democratic, describe, design, despite, detail, determine, develop, development,
32 die, difference, different, difficult, dinner, direction, director, discover,
33 discuss, discussion, disease, do, doctor, dog, door, down, draw, dream, drive,
34 drop, drug, during, each, early, east, easy, eat, economic, economy, edge,
35 education, effect, effort, eight, either, election, else, employee, end, energy,
36 enjoy, enough, enter, entire, environment, environmental, especially, establish,
37 even, evening, event, ever, every, everybody, everyone, everything, evidence,
38 exactly, example, executive, exist, expect, experience, expert, explain, eye,
39 face, fact, factor, fail, fall, family, far, fast, father, fear, federal, feel,
40 feeling, few, field, fight, figure, fill, film, final, finally, financial, find,
41 fine, finger, finish, fire, firm, first, fish, five, floor, fly, focus, follow,
42 food, foot, for, force, foreign, forget, form, former, forward, four, free,
43 friend, from, front, full, fund, future, game, garden, gas, general, generation,
44 get, girl, give, glass, go, goal, good, government, great, green, ground, group,
45 grow, growth, guess, gun, guy, hair, half, hand, hang, happen, happy, hard,
46 have, he, head, health, hear, heart, heat, heavy, help, her, here, herself,
47 high, him, himself, his, history, hit, hold, home, hope, hospital, hot, hotel,
48 hour, house, how, however, huge, human, hundred, husband, I, idea, identify, if,
49 image, imagine, impact, important, improve, in, include, including, increase,
50 indeed, indicate, individual, industry, information, inside, instead,
51 institution, interest, interesting, international, interview, into, investment,
52 involve, issue, it, item, its, itself, job, join, just, keep, key, kid, kill,
53 kind, kitchen, know, knowledge, land, language, large, last, late, later, laugh,
54 law, lawyer, lay, lead, leader, learn, least, leave, left, leg, legal, less,
55 let, letter, level, lie, life, light, like, likely, line, list, listen, little,
56 live, local, long, look, lose, loss, lot, love, low, machine, magazine, main,
57 maintain, major, majority, make, man, manage, management, manager, many, market,
58 marriage, material, matter, may, maybe, me, mean, measure, media, medical, meet,
59 meeting, member, memory, mention, message, method, middle, might, military,
60 million, mind, minute, miss, mission, model, modern, moment, money, month, more,
61 morning, most, mother, mouth, move, movement, movie, Mr, Mrs, much, music, must,
62 my, myself, name, nation, national, natural, nature, near, nearly, necessary,
63 need, network, never, new, news, newspaper, next, nice, night, no, none, nor,
64 north, not, note, nothing, notice, now, n't, number, occur, of, off, offer,
65 office, officer, official, often, oh, oil, ok, old, on, once, one, only, onto,
66 open, operation, opportunity, option, or, order, organization, other, others,
67 our, out, outside, over, own, owner, page, pain, painting, paper, parent, part,
68 participant, particular, particularly, partner, party, pass, past, patient,
69 pattern, pay, peace, people, per, perform, performance, perhaps, period, person,
70 personal, phone, physical, pick, picture, piece, place, plan, plant, play,
71 player, PM, point, police, policy, political, politics, poor, popular,
72 population, position, positive, possible, power, practice, prepare, present,
73 president, pressure, pretty, prevent, price, private, probably, problem,
74 process, produce, product, production, professional, professor, program,
75 project, property, protect, prove, provide, public, pull, purpose, push, put,
76 quality, question, quickly, quite, race, radio, raise, range, rate, rather,
77 reach, read, ready, real, reality, realize, really, reason, receive, recent,
78 recently, recognize, record, red, reduce, reflect, region, relate, relationship,
79 religious, remain, remember, remove, report, represent, Republican, require,
80 research, resource, respond, response, responsibility, rest, result, return,
81 reveal, rich, right, rise, risk, road, rock, role, room, rule, run, safe, same,
82 save, say, scene, school, science, scientist, score, sea, season, seat, second,
83 section, security, see, seek, seem, sell, send, senior, sense, series, serious,
84 serve, service, set, seven, several, sex, sexual, shake, share, she, shoot,
85 short, shot, should, shoulder, show, side, sign, significant, similar, simple,
86 simply, since, sing, single, sister, sit, site, situation, six, size, skill,
87 skin, small, smile, so, social, society, soldier, some, somebody, someone,
88 something, sometimes, son, song, soon, sort, sound, source, south, southern,
89 space, speak, special, specific, speech, spend, sport, spring, staff, stage,
90 stand, standard, star, start, state, statement, station, stay, step, still,
91 stock, stop, store, story, strategy, street, strong, structure, student, study,
92 stuff, style, subject, success, successful, such, suddenly, suffer, suggest,
93 summer, support, sure, surface, system, table, take, talk, task, tax, teach,
94 teacher, team, technology, television, tell, ten, tend, term, test, than, thank,
95 that, the, their, them, themselves, then, theory, there, these, they, thing,
96 think, third, this, those, though, thought, thousand, threat, three, through,
97 throughout, throw, thus, time, to, today, together, tonight, too, top, total,
98 tough, toward, town, trade, traditional, training, travel, treat, treatment,
99 tree, trial, trip, trouble, true, truth, try, turn, TV, two, type, under,
100 understand, unit, until, up, upon, us, use, usually, value, various, very,
101 victim, view, violence, visit, voice, vote, wait, walk, wall, want, war, watch,
102 water, way, we, weapon, wear, week, weight, well, west, western, what, whatever,
103 when, where, whether, which, while, white, who, whole, whom, whose, why, wide,
104 wife, will, win, wind, window, wish, with, within, without, woman, wonder, word,
105 work, worker, world, worry, would, write, writer, wrong, yard, yeah, year, yes,
106 yet, you, young, your, yourself"#
107 .split(',')
108 .map(|word| word.trim())
109 .collect();
110
111 let mut word_pairs: Vec<_> = Vec::new();
112 for word in &words {
113 for other_word in &words {
114 word_pairs.push(word.to_string() + " " + other_word);
115 }
116 }
117 assert_eq!(1_000_000, word_pairs.len());
118 word_pairs
119 }
120
121 #[allow(unused)] // False positive
test_hash_common_words<T: Hasher>(hasher: impl Fn() -> T)122 fn test_hash_common_words<T: Hasher>(hasher: impl Fn() -> T) {
123 let word_pairs: Vec<_> = gen_word_pairs();
124 check_for_collisions(&hasher, &word_pairs, 32);
125 }
126
127 #[allow(unused)] // False positive
check_for_collisions<T: Hasher, H: Hash>(hasher: &impl Fn() -> T, items: &[H], bucket_count: usize)128 fn check_for_collisions<T: Hasher, H: Hash>(hasher: &impl Fn() -> T, items: &[H], bucket_count: usize) {
129 let mut buckets = vec![0; bucket_count];
130 for item in items {
131 let value = hash(item, &hasher) as usize;
132 buckets[value % bucket_count] += 1;
133 }
134 let mean = items.len() / bucket_count;
135 let max = *buckets.iter().max().unwrap();
136 let min = *buckets.iter().min().unwrap();
137 assert!(
138 (min as f64) > (mean as f64) * 0.95,
139 "min: {}, max:{}, {:?}",
140 min,
141 max,
142 buckets
143 );
144 assert!(
145 (max as f64) < (mean as f64) * 1.05,
146 "min: {}, max:{}, {:?}",
147 min,
148 max,
149 buckets
150 );
151 }
152
153 #[allow(unused)] // False positive
hash<H: Hash, T: Hasher>(b: &H, hasher: &dyn Fn() -> T) -> u64154 fn hash<H: Hash, T: Hasher>(b: &H, hasher: &dyn Fn() -> T) -> u64 {
155 let hasher = hasher();
156 H::get_hash(b, hasher)
157 }
158
159 #[test]
test_bucket_distribution()160 fn test_bucket_distribution() {
161 let hasher = || AHasher::new_with_keys(123456789, 987654321);
162 test_hash_common_words(&hasher);
163 let sequence: Vec<_> = (0..320000).collect();
164 check_for_collisions(&hasher, &sequence, 32);
165 let sequence: Vec<_> = (0..2560000).collect();
166 check_for_collisions(&hasher, &sequence, 256);
167 let sequence: Vec<_> = (0..320000).map(|i| i * 1024).collect();
168 check_for_collisions(&hasher, &sequence, 32);
169 let sequence: Vec<_> = (0..2560000_u64).map(|i| i * 1024).collect();
170 check_for_collisions(&hasher, &sequence, 256);
171 }
172
ahash_vec<H: Hash>(b: &Vec<H>) -> u64173 fn ahash_vec<H: Hash>(b: &Vec<H>) -> u64 {
174 let mut total: u64 = 0;
175 for item in b {
176 let mut hasher = AHasher::new_with_keys(1234, 5678);
177 item.hash(&mut hasher);
178 total = total.wrapping_add(hasher.finish());
179 }
180 total
181 }
182
fxhash_vec<H: Hash>(b: &Vec<H>) -> u64183 fn fxhash_vec<H: Hash>(b: &Vec<H>) -> u64 {
184 let mut total: u64 = 0;
185 for item in b {
186 let mut hasher = FxHasher::default();
187 item.hash(&mut hasher);
188 total = total.wrapping_add(hasher.finish());
189 }
190 total
191 }
192
bench_ahash_words(c: &mut Criterion)193 fn bench_ahash_words(c: &mut Criterion) {
194 let words = gen_word_pairs();
195 c.bench_function("aes_words", |b| b.iter(|| black_box(ahash_vec(&words))));
196 }
197
bench_fx_words(c: &mut Criterion)198 fn bench_fx_words(c: &mut Criterion) {
199 let words = gen_word_pairs();
200 c.bench_function("fx_words", |b| b.iter(|| black_box(fxhash_vec(&words))));
201 }
202
203 criterion_main!(benches);
204 criterion_group!(benches, bench_ahash_words, bench_fx_words,);
205