summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ahash/tests
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/ahash/tests')
-rw-r--r--third_party/rust/ahash/tests/bench.rs154
-rw-r--r--third_party/rust/ahash/tests/map_tests.rs203
-rw-r--r--third_party/rust/ahash/tests/nopanic.rs72
3 files changed, 429 insertions, 0 deletions
diff --git a/third_party/rust/ahash/tests/bench.rs b/third_party/rust/ahash/tests/bench.rs
new file mode 100644
index 0000000000..9e6dccc481
--- /dev/null
+++ b/third_party/rust/ahash/tests/bench.rs
@@ -0,0 +1,154 @@
+use ahash::{CallHasher, RandomState};
+use criterion::*;
+use fxhash::FxHasher;
+use std::collections::hash_map::DefaultHasher;
+use std::hash::{Hash, Hasher};
+
+#[cfg(any(
+ all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
+ all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "crypto", not(miri), feature = "stdsimd")
+))]
+fn aeshash<H: Hash>(b: &H) -> u64 {
+ let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
+ H::get_hash(b, &build_hasher)
+}
+#[cfg(not(any(
+ all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
+ all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "crypto", not(miri), feature = "stdsimd")
+)))]
+fn aeshash<H: Hash>(_b: &H) -> u64 {
+ panic!("aes must be enabled")
+}
+
+#[cfg(not(any(
+ all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
+ all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "crypto", not(miri), feature = "stdsimd")
+)))]
+fn fallbackhash<H: Hash>(b: &H) -> u64 {
+ let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
+ H::get_hash(b, &build_hasher)
+}
+#[cfg(any(
+ all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
+ all(any(target_arch = "arm", target_arch = "aarch64"), target_feature = "crypto", not(miri), feature = "stdsimd")
+))]
+fn fallbackhash<H: Hash>(_b: &H) -> u64 {
+ panic!("aes must be disabled")
+}
+
+fn fnvhash<H: Hash>(b: &H) -> u64 {
+ let mut hasher = fnv::FnvHasher::default();
+ b.hash(&mut hasher);
+ hasher.finish()
+}
+
+fn siphash<H: Hash>(b: &H) -> u64 {
+ let mut hasher = DefaultHasher::default();
+ b.hash(&mut hasher);
+ hasher.finish()
+}
+
+fn fxhash<H: Hash>(b: &H) -> u64 {
+ let mut hasher = FxHasher::default();
+ b.hash(&mut hasher);
+ hasher.finish()
+}
+
+fn seahash<H: Hash>(b: &H) -> u64 {
+ let mut hasher = seahash::SeaHasher::default();
+ b.hash(&mut hasher);
+ hasher.finish()
+}
+
+const STRING_LENGTHS: [u32; 12] = [1, 3, 4, 7, 8, 15, 16, 24, 33, 68, 132, 1024];
+
+fn gen_strings() -> Vec<String> {
+ STRING_LENGTHS
+ .iter()
+ .map(|len| {
+ let mut string = String::default();
+ for pos in 1..=*len {
+ let c = (48 + (pos % 10) as u8) as char;
+ string.push(c);
+ }
+ string
+ })
+ .collect()
+}
+
+const U8_VALUE: u8 = 123;
+const U16_VALUE: u16 = 1234;
+const U32_VALUE: u32 = 12345678;
+const U64_VALUE: u64 = 1234567890123456;
+const U128_VALUE: u128 = 12345678901234567890123456789012;
+
+fn bench_ahash(c: &mut Criterion) {
+ let mut group = c.benchmark_group("aeshash");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(aeshash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(aeshash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(aeshash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(aeshash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(aeshash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(aeshash(s))));
+}
+
+fn bench_fallback(c: &mut Criterion) {
+ let mut group = c.benchmark_group("fallback");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fallbackhash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fallbackhash(s))));
+}
+
+fn bench_fx(c: &mut Criterion) {
+ let mut group = c.benchmark_group("fx");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fxhash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fxhash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fxhash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fxhash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fxhash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fxhash(s))));
+}
+
+fn bench_fnv(c: &mut Criterion) {
+ let mut group = c.benchmark_group("fnv");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(fnvhash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(fnvhash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(fnvhash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(fnvhash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(fnvhash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(fnvhash(s))));
+}
+
+fn bench_sea(c: &mut Criterion) {
+ let mut group = c.benchmark_group("sea");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(seahash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(seahash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(seahash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(seahash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(seahash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(seahash(s))));
+}
+
+fn bench_sip(c: &mut Criterion) {
+ let mut group = c.benchmark_group("sip");
+ group.bench_with_input("u8", &U8_VALUE, |b, s| b.iter(|| black_box(siphash(s))));
+ group.bench_with_input("u16", &U16_VALUE, |b, s| b.iter(|| black_box(siphash(s))));
+ group.bench_with_input("u32", &U32_VALUE, |b, s| b.iter(|| black_box(siphash(s))));
+ group.bench_with_input("u64", &U64_VALUE, |b, s| b.iter(|| black_box(siphash(s))));
+ group.bench_with_input("u128", &U128_VALUE, |b, s| b.iter(|| black_box(siphash(s))));
+ group.bench_with_input("string", &gen_strings(), |b, s| b.iter(|| black_box(siphash(s))));
+}
+
+criterion_main!(benches);
+criterion_group!(
+ benches,
+ bench_ahash,
+ bench_fallback,
+ bench_fx,
+ bench_fnv,
+ bench_sea,
+ bench_sip
+);
diff --git a/third_party/rust/ahash/tests/map_tests.rs b/third_party/rust/ahash/tests/map_tests.rs
new file mode 100644
index 0000000000..be617a2e72
--- /dev/null
+++ b/third_party/rust/ahash/tests/map_tests.rs
@@ -0,0 +1,203 @@
+use std::hash::{BuildHasher, Hash, Hasher};
+
+use criterion::*;
+use fxhash::FxHasher;
+
+use ahash::{AHasher, CallHasher, RandomState};
+
+fn gen_word_pairs() -> Vec<String> {
+ let words: Vec<_> = r#"
+a, ability, able, about, above, accept, according, account, across, act, action,
+activity, actually, add, address, administration, admit, adult, affect, after,
+again, against, age, agency, agent, ago, agree, agreement, ahead, air, all,
+allow, almost, alone, along, already, also, although, always, American, among,
+amount, analysis, and, animal, another, answer, any, anyone, anything, appear,
+apply, approach, area, argue, arm, around, arrive, art, article, artist, as,
+ask, assume, at, attack, attention, attorney, audience, author, authority,
+available, avoid, away, baby, back, bad, bag, ball, bank, bar, base, be, beat,
+beautiful, because, become, bed, before, begin, behavior, behind, believe,
+benefit, best, better, between, beyond, big, bill, billion, bit, black, blood,
+blue, board, body, book, born, both, box, boy, break, bring, brother, budget,
+build, building, business, but, buy, by, call, camera, campaign, can, cancer,
+candidate, capital, car, card, care, career, carry, case, catch, cause, cell,
+center, central, century, certain, certainly, chair, challenge, chance, change,
+character, charge, check, child, choice, choose, church, citizen, city, civil,
+claim, class, clear, clearly, close, coach, cold, collection, college, color,
+come, commercial, common, community, company, compare, computer, concern,
+condition, conference, Congress, consider, consumer, contain, continue, control,
+cost, could, country, couple, course, court, cover, create, crime, cultural,
+culture, cup, current, customer, cut, dark, data, daughter, day, dead, deal,
+death, debate, decade, decide, decision, deep, defense, degree, Democrat,
+democratic, describe, design, despite, detail, determine, develop, development,
+die, difference, different, difficult, dinner, direction, director, discover,
+discuss, discussion, disease, do, doctor, dog, door, down, draw, dream, drive,
+drop, drug, during, each, early, east, easy, eat, economic, economy, edge,
+education, effect, effort, eight, either, election, else, employee, end, energy,
+enjoy, enough, enter, entire, environment, environmental, especially, establish,
+even, evening, event, ever, every, everybody, everyone, everything, evidence,
+exactly, example, executive, exist, expect, experience, expert, explain, eye,
+face, fact, factor, fail, fall, family, far, fast, father, fear, federal, feel,
+feeling, few, field, fight, figure, fill, film, final, finally, financial, find,
+fine, finger, finish, fire, firm, first, fish, five, floor, fly, focus, follow,
+food, foot, for, force, foreign, forget, form, former, forward, four, free,
+friend, from, front, full, fund, future, game, garden, gas, general, generation,
+get, girl, give, glass, go, goal, good, government, great, green, ground, group,
+grow, growth, guess, gun, guy, hair, half, hand, hang, happen, happy, hard,
+have, he, head, health, hear, heart, heat, heavy, help, her, here, herself,
+high, him, himself, his, history, hit, hold, home, hope, hospital, hot, hotel,
+hour, house, how, however, huge, human, hundred, husband, I, idea, identify, if,
+image, imagine, impact, important, improve, in, include, including, increase,
+indeed, indicate, individual, industry, information, inside, instead,
+institution, interest, interesting, international, interview, into, investment,
+involve, issue, it, item, its, itself, job, join, just, keep, key, kid, kill,
+kind, kitchen, know, knowledge, land, language, large, last, late, later, laugh,
+law, lawyer, lay, lead, leader, learn, least, leave, left, leg, legal, less,
+let, letter, level, lie, life, light, like, likely, line, list, listen, little,
+live, local, long, look, lose, loss, lot, love, low, machine, magazine, main,
+maintain, major, majority, make, man, manage, management, manager, many, market,
+marriage, material, matter, may, maybe, me, mean, measure, media, medical, meet,
+meeting, member, memory, mention, message, method, middle, might, military,
+million, mind, minute, miss, mission, model, modern, moment, money, month, more,
+morning, most, mother, mouth, move, movement, movie, Mr, Mrs, much, music, must,
+my, myself, name, nation, national, natural, nature, near, nearly, necessary,
+need, network, never, new, news, newspaper, next, nice, night, no, none, nor,
+north, not, note, nothing, notice, now, n't, number, occur, of, off, offer,
+office, officer, official, often, oh, oil, ok, old, on, once, one, only, onto,
+open, operation, opportunity, option, or, order, organization, other, others,
+our, out, outside, over, own, owner, page, pain, painting, paper, parent, part,
+participant, particular, particularly, partner, party, pass, past, patient,
+pattern, pay, peace, people, per, perform, performance, perhaps, period, person,
+personal, phone, physical, pick, picture, piece, place, plan, plant, play,
+player, PM, point, police, policy, political, politics, poor, popular,
+population, position, positive, possible, power, practice, prepare, present,
+president, pressure, pretty, prevent, price, private, probably, problem,
+process, produce, product, production, professional, professor, program,
+project, property, protect, prove, provide, public, pull, purpose, push, put,
+quality, question, quickly, quite, race, radio, raise, range, rate, rather,
+reach, read, ready, real, reality, realize, really, reason, receive, recent,
+recently, recognize, record, red, reduce, reflect, region, relate, relationship,
+religious, remain, remember, remove, report, represent, Republican, require,
+research, resource, respond, response, responsibility, rest, result, return,
+reveal, rich, right, rise, risk, road, rock, role, room, rule, run, safe, same,
+save, say, scene, school, science, scientist, score, sea, season, seat, second,
+section, security, see, seek, seem, sell, send, senior, sense, series, serious,
+serve, service, set, seven, several, sex, sexual, shake, share, she, shoot,
+short, shot, should, shoulder, show, side, sign, significant, similar, simple,
+simply, since, sing, single, sister, sit, site, situation, six, size, skill,
+skin, small, smile, so, social, society, soldier, some, somebody, someone,
+something, sometimes, son, song, soon, sort, sound, source, south, southern,
+space, speak, special, specific, speech, spend, sport, spring, staff, stage,
+stand, standard, star, start, state, statement, station, stay, step, still,
+stock, stop, store, story, strategy, street, strong, structure, student, study,
+stuff, style, subject, success, successful, such, suddenly, suffer, suggest,
+summer, support, sure, surface, system, table, take, talk, task, tax, teach,
+teacher, team, technology, television, tell, ten, tend, term, test, than, thank,
+that, the, their, them, themselves, then, theory, there, these, they, thing,
+think, third, this, those, though, thought, thousand, threat, three, through,
+throughout, throw, thus, time, to, today, together, tonight, too, top, total,
+tough, toward, town, trade, traditional, training, travel, treat, treatment,
+tree, trial, trip, trouble, true, truth, try, turn, TV, two, type, under,
+understand, unit, until, up, upon, us, use, usually, value, various, very,
+victim, view, violence, visit, voice, vote, wait, walk, wall, want, war, watch,
+water, way, we, weapon, wear, week, weight, well, west, western, what, whatever,
+when, where, whether, which, while, white, who, whole, whom, whose, why, wide,
+wife, will, win, wind, window, wish, with, within, without, woman, wonder, word,
+work, worker, world, worry, would, write, writer, wrong, yard, yeah, year, yes,
+yet, you, young, your, yourself"#
+ .split(',')
+ .map(|word| word.trim())
+ .collect();
+
+ let mut word_pairs: Vec<_> = Vec::new();
+ for word in &words {
+ for other_word in &words {
+ word_pairs.push(word.to_string() + " " + other_word);
+ }
+ }
+ assert_eq!(1_000_000, word_pairs.len());
+ word_pairs
+}
+
+#[allow(unused)] // False positive
+fn test_hash_common_words<B: BuildHasher>(build_hasher: &B) {
+ let word_pairs: Vec<_> = gen_word_pairs();
+ check_for_collisions(build_hasher, &word_pairs, 32);
+}
+
+#[allow(unused)] // False positive
+fn check_for_collisions<H: Hash, B: BuildHasher>(build_hasher: &B, items: &[H], bucket_count: usize) {
+ let mut buckets = vec![0; bucket_count];
+ for item in items {
+ let value = hash(item, build_hasher) as usize;
+ buckets[value % bucket_count] += 1;
+ }
+ let mean = items.len() / bucket_count;
+ let max = *buckets.iter().max().unwrap();
+ let min = *buckets.iter().min().unwrap();
+ assert!(
+ (min as f64) > (mean as f64) * 0.95,
+ "min: {}, max:{}, {:?}",
+ min,
+ max,
+ buckets
+ );
+ assert!(
+ (max as f64) < (mean as f64) * 1.05,
+ "min: {}, max:{}, {:?}",
+ min,
+ max,
+ buckets
+ );
+}
+
+#[allow(unused)] // False positive
+fn hash<H: Hash, B: BuildHasher>(b: &H, build_hasher: &B) -> u64 {
+ H::get_hash(b, build_hasher)
+}
+
+#[test]
+fn test_bucket_distribution() {
+ let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
+ test_hash_common_words(&build_hasher);
+ let sequence: Vec<_> = (0..320000).collect();
+ check_for_collisions(&build_hasher, &sequence, 32);
+ let sequence: Vec<_> = (0..2560000).collect();
+ check_for_collisions(&build_hasher, &sequence, 256);
+ let sequence: Vec<_> = (0..320000).map(|i| i * 1024).collect();
+ check_for_collisions(&build_hasher, &sequence, 32);
+ let sequence: Vec<_> = (0..2560000_u64).map(|i| i * 1024).collect();
+ check_for_collisions(&build_hasher, &sequence, 256);
+}
+
+fn ahash_vec<H: Hash>(b: &Vec<H>) -> u64 {
+ let mut total: u64 = 0;
+ for item in b {
+ let mut hasher = AHasher::new_with_keys(1234, 5678);
+ item.hash(&mut hasher);
+ total = total.wrapping_add(hasher.finish());
+ }
+ total
+}
+
+fn fxhash_vec<H: Hash>(b: &Vec<H>) -> u64 {
+ let mut total: u64 = 0;
+ for item in b {
+ let mut hasher = FxHasher::default();
+ item.hash(&mut hasher);
+ total = total.wrapping_add(hasher.finish());
+ }
+ total
+}
+
+fn bench_ahash_words(c: &mut Criterion) {
+ let words = gen_word_pairs();
+ c.bench_function("aes_words", |b| b.iter(|| black_box(ahash_vec(&words))));
+}
+
+fn bench_fx_words(c: &mut Criterion) {
+ let words = gen_word_pairs();
+ c.bench_function("fx_words", |b| b.iter(|| black_box(fxhash_vec(&words))));
+}
+
+criterion_main!(benches);
+criterion_group!(benches, bench_ahash_words, bench_fx_words,);
diff --git a/third_party/rust/ahash/tests/nopanic.rs b/third_party/rust/ahash/tests/nopanic.rs
new file mode 100644
index 0000000000..d48ff559d2
--- /dev/null
+++ b/third_party/rust/ahash/tests/nopanic.rs
@@ -0,0 +1,72 @@
+use ahash::{AHasher, CallHasher, RandomState};
+use std::hash::BuildHasher;
+
+#[macro_use]
+extern crate no_panic;
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_final(num: i32, string: &str) -> (u64, u64) {
+ use core::hash::Hasher;
+ let mut hasher1 = AHasher::new_with_keys(1, 2);
+ let mut hasher2 = AHasher::new_with_keys(3, 4);
+ hasher1.write_i32(num);
+ hasher2.write(string.as_bytes());
+ (hasher1.finish(), hasher2.finish())
+}
+
+#[inline(never)]
+fn hash_test_final_wrapper(num: i32, string: &str) {
+ hash_test_final(num, string);
+}
+
+struct SimpleBuildHasher {
+ hasher: AHasher,
+}
+
+impl BuildHasher for SimpleBuildHasher {
+ type Hasher = AHasher;
+
+ fn build_hasher(&self) -> Self::Hasher {
+ self.hasher.clone()
+ }
+}
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_specialize(num: i32, string: &str) -> (u64, u64) {
+ let hasher1 = AHasher::new_with_keys(1, 2);
+ let hasher2 = AHasher::new_with_keys(1, 2);
+ (
+ i32::get_hash(&num, &SimpleBuildHasher { hasher: hasher1 }),
+ <[u8]>::get_hash(string.as_bytes(), &SimpleBuildHasher { hasher: hasher2 }),
+ )
+}
+
+#[inline(never)]
+fn hash_test_random_wrapper(num: i32, string: &str) {
+ hash_test_specialize(num, string);
+}
+
+#[inline(never)]
+#[no_panic]
+fn hash_test_random(num: i32, string: &str) -> (u64, u64) {
+ let build_hasher1 = RandomState::with_seeds(1, 2, 3, 4);
+ let build_hasher2 = RandomState::with_seeds(1, 2, 3, 4);
+ (
+ i32::get_hash(&num, &build_hasher1),
+ <[u8]>::get_hash(string.as_bytes(), &build_hasher2),
+ )
+}
+
+#[inline(never)]
+fn hash_test_specialize_wrapper(num: i32, string: &str) {
+ hash_test_specialize(num, string);
+}
+
+#[test]
+fn test_no_panic() {
+ hash_test_final_wrapper(2, "Foo");
+ hash_test_specialize_wrapper(2, "Bar");
+ hash_test_random_wrapper(2, "Baz");
+}