-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use SmallVec
for better performance
#57
Comments
Could definitely be worth looking into. There is an |
I will do it. Maybe it's worth to add more benchmarks before that. How do you feel about introducing the dependency
I ran it multiple times and it was consistent.
Would you mind switching to another bench lib like criterion or divan (my preferred choice)? They support this out of the box. And the current benchmark requires a nightly compiler which is a little bit annoying. |
Looked a bit at both of the benchmark libs. Both don't seems very active so I suppose divan should be fine. |
I'm confused because my optimization improved the benchmark from issue #64, but not the existing benchmark So the I compared the collisions in both benchmarks: use intmap::IntMap;
pub fn main() {
// Based on the benchmark from issue #46
let mut map = IntMap::new();
for i in 0..10_000 {
map.insert(i, i);
}
println!("A: {:?}", map.collisions());
// Based on benchmark u64_insert_intmap_without_capacity
let data = get_random_range(10_000);
let mut map = IntMap::new();
for s in data.iter() {
map.insert(*s, s);
}
println!("B: {:?}", map.collisions());
}
fn get_random_range(count: usize) -> Vec<u64> {
use rand::prelude::StdRng;
use rand::{Rng, SeedableRng};
let mut vec = Vec::new();
let mut rng = StdRng::seed_from_u64(10);
for _ in 0..count {
vec.push(rng.gen::<u64>());
}
vec.sort();
vec.dedup();
vec
} Here the result:
When using random values, there are 1675 collisions for slot 2! What's going on? Does the random number generator use the same prime number as our hashing function? |
Ah, I misinterpreted the output:
|
If smallvec could fit at least 2 items it should be a decent boon to performance. |
Unfortunately it did not improve the performance according to my benchmarks. I need more time for investigation. |
Currently
IntMap
stores it values in this data structure:If I understand correctly the inner
Vec
is used for entries with a hash collision. I would assume that hash collisions are rare, so allocating aVec
for storing a single entry might be too expensive.A simple solution to this problem could be
SmallVec
:I refactored
IntMap
and ran the benchmarks included in this repo:It doesn't seem to make a difference. But then I ran the benchmarks mentioned #46:
This looks good, isn't it? My changes are on this branch.
What do you think? Is it worth to investigate this further?
The text was updated successfully, but these errors were encountered: