Skip to content

Commit 5adef52

Browse files
bors[bot]tkaitchuckAmanieu
committed
Merge #56 #62
56: Add additional benchmarks. r=Amanieu a=tkaitchuck This covers performance of three cases I wanted to study when looking into https://github.com/Amanieu/hashbrown/issues/48 They are: `grow_by_insertion_kb` which is similar to grow by insertion, but instead of every entry differing by 1, they differ by 1024. This makes an important performance difference to the hasher. `find_existing_high_bits` which is similar to find_existing but uses 64 bit keys instead of 32 bit keys, where the lower 32 bits are zeros. This is a pathologically bad case for FxHash. `insert_8_char_string` tests a case where the key is a string. (As opposed to all the existing tests which operate on u32 values. This is important to cover because strings as keys are very common. 62: Remove incorrect debug_assert r=Amanieu a=Amanieu Fixes #60 Co-authored-by: Tom Kaitchuck <tom.kaitchuck@dell.com> Co-authored-by: Amanieu d'Antras <amanieu@gmail.com>
3 parents ab3e4ea + 1cf0503 + aea2f62 commit 5adef52

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

benches/bench.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ fn grow_by_insertion(b: &mut Bencher) {
4646
});
4747
}
4848

49+
#[bench]
50+
fn grow_by_insertion_kb(b: &mut Bencher) {
51+
let mut m = new_map();
52+
let kb = 1024;
53+
for i in 1..1001 {
54+
m.insert(i * kb, i);
55+
}
56+
57+
let mut k = 1001 * kb;
58+
59+
b.iter(|| {
60+
m.insert(k, k);
61+
k += kb;
62+
});
63+
}
64+
4965
#[bench]
5066
fn find_existing(b: &mut Bencher) {
5167
let mut m = new_map();
@@ -61,6 +77,21 @@ fn find_existing(b: &mut Bencher) {
6177
});
6278
}
6379

80+
#[bench]
81+
fn find_existing_high_bits(b: &mut Bencher) {
82+
let mut m = new_map();
83+
84+
for i in 1..1001_u64 {
85+
m.insert(i << 32, i);
86+
}
87+
88+
b.iter(|| {
89+
for i in 1..1001_u64 {
90+
m.contains_key(&(i << 32));
91+
}
92+
});
93+
}
94+
6495
#[bench]
6596
fn find_nonexisting(b: &mut Bencher) {
6697
let mut m = new_map();
@@ -111,3 +142,18 @@ fn get_remove_insert(b: &mut Bencher) {
111142
k += 1;
112143
})
113144
}
145+
146+
#[bench]
147+
fn insert_8_char_string(b: &mut Bencher) {
148+
let mut strings: Vec<_> = Vec::new();
149+
for i in 1..1001 {
150+
strings.push(format!("{:x}", -i));
151+
}
152+
153+
let mut m = new_map();
154+
b.iter(|| {
155+
for key in &strings {
156+
m.insert(key, key);
157+
}
158+
})
159+
}

src/raw/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,8 @@ fn special_is_empty(ctrl: u8) -> bool {
118118
#[inline]
119119
#[allow(clippy::cast_possible_truncation)]
120120
fn h1(hash: u64) -> usize {
121-
#[cfg(target_pointer_width = "32")]
122-
{
123-
debug_assert!(hash <= u64::from(u32::max_value()));
124-
}
125-
hash as usize // truncation
121+
// On 32-bit platforms we simply ignore the higher hash bits.
122+
hash as usize
126123
}
127124

128125
/// Secondary hash function, saved in the low 7 bits of the control byte.

0 commit comments

Comments
 (0)