Skip to content
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

fix clippy warnings, run cargo fmt, feature-gate c deps, improve benchmarks #3

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ keywords = [
]

[features]
# Link the C library for murmur3. You likely never need this feature.
# It exists purely for benchmarking and testing purposes.
"murmur3c"= []
# Link the C libraries for murmur3. These features make no difference for functionality and they should be disabled.
# They exist purely for benchmarking and testing purposes.
"murmur3c" = []
"fasthash" = ["dep:fasthash"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bench]]
Expand All @@ -31,13 +32,16 @@ path = "bench/bench.rs"
harness = false

[dependencies]
fasthash = { version = "0.4.0", optional = true }

[dev-dependencies]
criterion = "0.3.5"
murmur3 = "0.5.1"
sha-1 = "0.10.0"
rand = "0.8.4"
fasthash = "0.4.0"
xxhash-rust = { version = "0.8.2", features = ["xxh3"] }
twox-hash = "1.6.1"
rustc-hash = "1.1.0"
highway = "0.8.1"
fnv = "1.0.7"
crc = "3.0.1"
143 changes: 102 additions & 41 deletions bench/bench.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,118 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
#[cfg(feature = "fasthash")]
use fasthash::murmur3::Hash128_x64;
#[cfg(feature = "fasthash")]
use fasthash::FastHash;
use highway::HighwayHash;
use rand::RngCore;
use std::hash::Hasher;
use std::io::Cursor;
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use fasthash::FastHash;
use fasthash::murmur3::Hash128_x64;
use rustc_hash;

static SOURCE: &'static [u8] = b"The quick brown fox jumps over the lazy dog";


fn sha1(data: &[u8]) -> [u8; 20] {
use sha1::{Sha1, Digest};
use sha1::{Digest, Sha1};
// let mut hasher = Sha1::new();
<[u8; 20]>::from(Sha1::digest(data))
}


fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("hashes");

group.bench_function("sha1", |b| b.iter(||
sha1(SOURCE)
));
group.bench_function("fastmurmur3", |b| b.iter(||
fastmurmur3::hash(SOURCE)
));
group.bench_function("murmur3c", |b| b.iter(||
fastmurmur3::murmur3c::hash(SOURCE)
));
group.bench_function("fasthash", |b| b.iter(||
Hash128_x64::hash(SOURCE)
));
group.bench_function("murmur3", |b| b.iter(||
murmur3::murmur3_x64_128(&mut Cursor::new(SOURCE),0).unwrap()
));
group.bench_function("twox_hash::Xxh3Hash128", |b| b.iter(|| {
let mut h = twox_hash::xxh3::Hash128::default();
h.write(SOURCE);
h.finish()
}));
group.bench_function("twox_hash::Xxh3Hash64", |b| b.iter(|| {
let mut h = twox_hash::xxh3::Hash64::default();
h.write(SOURCE);
h.finish()
}));
group.bench_function("xxhash_rust::xxh3_64", |b| b.iter(||
xxhash_rust::xxh3::xxh3_64(SOURCE)
));
group.bench_function("xxhash_rust::xxh3_128", |b| b.iter(||
xxhash_rust::xxh3::xxh3_128(SOURCE)
));
for size in [
16, 20, 32, 40, 64, 70, 128, 130, 256, 260, 512, 520, 1024, 1030, 2048, 2050, 4096, 5500,
] {
let mut rng = rand::thread_rng();
let mut buf = vec![0; size];
rng.fill_bytes(&mut buf);

group.bench_with_input(BenchmarkId::new("sha1", size), &size, |b, _size| {
b.iter(|| sha1(&buf))
});

group.bench_with_input(BenchmarkId::new("fastmurmur3", size), &size, |b, _size| {
b.iter(|| fastmurmur3::hash(&buf))
});

#[cfg(feature = "murmur3c")]
group.bench_with_input(BenchmarkId::new("murmur3c", size), &size, |b, _size| {
b.iter(|| fastmurmur3::murmur3c::hash(&buf))
});

#[cfg(feature = "fasthash")]
group.bench_with_input(BenchmarkId::new("fasthash", size), &size, |b, _size| {
b.iter(|| Hash128_x64::hash(&buf))
});

group.bench_with_input(BenchmarkId::new("murmur3", size), &size, |b, _size| {
b.iter(|| murmur3::murmur3_x64_128(&mut Cursor::new(&buf), 0))
});

group.bench_with_input(
BenchmarkId::new("twox_hash::Xxh3Hash128", size),
&size,
|b, _size| {
b.iter(|| {
let mut h = twox_hash::xxh3::Hash128::default();
h.write(&buf);
h.finish()
})
},
);

group.bench_with_input(
BenchmarkId::new("twox_hash::Xxh3Hash64", size),
&size,
|b, _size| {
b.iter(|| {
let mut h = twox_hash::xxh3::Hash64::default();
h.write(&buf);
h.finish()
})
},
);

group.bench_with_input(
BenchmarkId::new("xxhash_rust::xxh3_64", size),
&size,
|b, _size| b.iter(|| xxhash_rust::xxh3::xxh3_64(&buf)),
);

group.bench_with_input(
BenchmarkId::new("xxhash_rust::xxh3_128", size),
&size,
|b, _size| b.iter(|| xxhash_rust::xxh3::xxh3_128(&buf)),
);

group.bench_with_input(
BenchmarkId::new("highway::HighwayHasher::hash128", size),
&size,
|b, _size| b.iter(|| highway::HighwayHasher::default().hash128(&buf)),
);

group.bench_with_input(BenchmarkId::new("fnv", size), &size, |b, _size| {
b.iter(|| {
let mut hasher = fnv::FnvHasher::default();
hasher.write(&buf);
hasher.finish()
})
});

group.bench_with_input(BenchmarkId::new("crc32", size), &size, |b, _size| {
b.iter(|| {
let hasher = crc::Crc::<u32>::new(&crc::CRC_32_ISCSI);
hasher.checksum(&buf)
})
});

group.bench_with_input(BenchmarkId::new("crc64", size), &size, |b, _size| {
b.iter(|| {
let hasher = crc::Crc::<u64>::new(&crc::CRC_64_ECMA_182);
hasher.checksum(&buf)
})
});
}

group.finish();
}


criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
2 changes: 1 addition & 1 deletion src/fallthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ fn it_works() {
_ => { panic!("Should not reach the default case"); },
});
assert_eq!(x, 2);
}
}
13 changes: 6 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
mod murmur3rs;
mod fallthrough;
mod murmur3rs;

pub use murmur3rs::{hash, murmur3_x64_128};

#[cfg(feature = "murmur3c")]
pub mod murmur3c;


#[cfg(test)]
#[cfg(feature = "murmur3c")]
mod test {
use super::*;
use rand::{Rng, RngCore};
Expand All @@ -33,14 +33,13 @@ mod test {
let a = murmur3rs::murmur3_x64_128(&buf, salt);
let b = murmur3c::murmur3_x64_128(&buf, salt);
assert_eq!(
a, b,
a,
b,
"Failed after {} iterations. salt={} data={}",
i,
salt,
buf.iter()
.map(|b| format!("{:x}", b))
.collect::<String>(),
buf.iter().map(|b| format!("{:x}", b)).collect::<String>(),
);
}
}
}
}
17 changes: 13 additions & 4 deletions src/murmur3c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ extern "C" {
pub fn hash(data: &[u8]) -> u128 {
let mut buf = [0u8; 16];
unsafe {
MurmurHash3_x64_128(data.as_ptr() as *const c_void, data.len() as i32, 0, &mut buf as *mut _ as *mut c_void);
MurmurHash3_x64_128(
data.as_ptr() as *const c_void,
data.len() as i32,
0,
&mut buf as *mut _ as *mut c_void,
);
}
if cfg!(target_endian = "big") {
u128::from_be_bytes(buf)
Expand All @@ -22,16 +27,20 @@ pub fn hash(data: &[u8]) -> u128 {
}
}


#[cfg(target_pointer_width = "64")]
pub fn murmur3_x64_128(data: &[u8], salt: u32) -> u128 {
let mut buf = [0u8; 16];
unsafe {
MurmurHash3_x64_128(data.as_ptr() as *const c_void, data.len() as i32, salt, &mut buf as *mut _ as *mut c_void);
MurmurHash3_x64_128(
data.as_ptr() as *const c_void,
data.len() as i32,
salt,
&mut buf as *mut _ as *mut c_void,
);
}
if cfg!(target_endian = "big") {
u128::from_be_bytes(buf)
} else {
u128::from_le_bytes(buf)
}
}
}
Loading