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

Go for tmp construction with 128 and 256 bit versions + FFI #3

Merged
merged 9 commits into from
Oct 28, 2023
Merged
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
2 changes: 2 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
rustflags = ["-C", "target-cpu=native"]
13 changes: 9 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
[package]
name = "gxhash"
author = "Olivier Giniaux"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[profile.release]
debug = true
[features]
# The 256-bit state GxHash is faster for large inputs than the default 128-bit state implementation.
# Please not however that the 256-bit GxHash and the 128-bit GxHash don't generate the same hashes for a same input.
# Requires AVX2 and VAES (X86).
256-bit = []

[dependencies]
rand = "0.8"

[dev-dependencies]
rstest = "0.18.2"
criterion = { version = "0.5.1" }
lazy_static = { version = "1.3" }
# Other hash algorithms, for comparison.
ahash = "0.8.3"
t1ha = "0.1.0"
twox-hash = "1.6.3"
highway = "1.1.0"

[[bench]]
name = "throughput"
Expand Down
14 changes: 14 additions & 0 deletions benches/fnv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const INITIAL_STATE: u64 = 0xcbf29ce484222325;
const PRIME: u64 = 0x100000001b3;

#[inline]
pub const fn fnv_hash(bytes: &[u8]) -> u64 {
let mut hash = INITIAL_STATE;
let mut i = 0;
while i < bytes.len() {
hash = hash ^ (bytes[i] as u64);
hash = hash.wrapping_mul(PRIME);
i += 1;
}
hash
}
48 changes: 29 additions & 19 deletions benches/throughput.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
#![feature(build_hasher_simple_hash_one)]

use std::time::Duration;
use std::alloc::{alloc, dealloc, Layout};
use std::slice;

use criterion::measurement::{WallTime};
use criterion::measurement::WallTime;
use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput, PlotConfiguration, AxisScale, BenchmarkGroup, BenchmarkId};
use gxhash::*;
use rand::Rng;

use gxhash::*;
mod fnv;

fn benchmark<F>(c: &mut BenchmarkGroup<WallTime>, data: &[u8], name: &str, delegate: F)
where F: Fn(&[u8], i32) -> u64
{
for i in 1..16 {
let len = usize::pow(2, i);
for i in 1.. {
let len = usize::pow(4, i);
if len > data.len() {
break;
}

c.throughput(Throughput::Bytes(len as u64));

let aligned_slice = &data[0..len];
c.bench_with_input(BenchmarkId::new(name, len), aligned_slice, |bencher, input| {
let slice = &data[0..len]; // Aligned
// let slice = &data[1..len]; // Unaligned
c.bench_with_input(BenchmarkId::new(name, len), slice, |bencher, input| {
bencher.iter(|| black_box(delegate(input, 0)))
});

// let unaligned_slice = &slice[1..len];
// group.bench_with_input(format!("{} bytes (unaligned)", len), unaligned_slice, |bencher, input| {
// bencher.iter(|| black_box(gxhash(input)))
// });
}
}

Expand All @@ -45,19 +44,19 @@ fn benchmark_all(c: &mut Criterion) {
group.plot_config(plot_config);

// GxHash0
benchmark(&mut group, slice, "gxhash0", |data: &[u8], _: i32| -> u64 {
gxhash0_64(data, 0)
});
// benchmark(&mut group, slice, "gxhash0", |data: &[u8], _: i32| -> u64 {
// gxhash0_64(data, 0)
// });

// GxHash1
benchmark(&mut group, slice, "gxhash1", |data: &[u8], _: i32| -> u64 {
benchmark(&mut group, slice, "gxhash", |data: &[u8], _: i32| -> u64 {
gxhash1_64(data, 0)
});

// AHash
let build_hasher = ahash::RandomState::with_seeds(0, 0, 0, 0);
let ahash_hasher = ahash::RandomState::with_seeds(0, 0, 0, 0);
benchmark(&mut group, slice, "ahash", |data: &[u8], _: i32| -> u64 {
build_hasher.hash_one(data)
ahash_hasher.hash_one(data)
});

// T1ha0
Expand All @@ -70,6 +69,17 @@ fn benchmark_all(c: &mut Criterion) {
twox_hash::xxh3::hash64_with_seed(data, seed as u64)
});

// HighwayHash
benchmark(&mut group, slice, "highwayhash", |data: &[u8], _: i32| -> u64 {
use highway::{HighwayHasher, HighwayHash};
HighwayHasher::default().hash64(data)
});

// FNV-1a
benchmark(&mut group, slice, "fnv-1a", |data: &[u8], _: i32| -> u64 {
fnv::fnv_hash(data)
});

group.finish();

// Free benchmark data
Expand Down
136 changes: 0 additions & 136 deletions c/gxhash.c

This file was deleted.

9 changes: 0 additions & 9 deletions c/gxhash.h

This file was deleted.

12 changes: 12 additions & 0 deletions ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "gxhash_ffi"
author = "Olivier Giniaux"
version = "0.1.0"
edition = "2021"

[lib]
name = "gxhash"
crate-type = ["cdylib", "staticlib"]

[dependencies]
gxhash = { path = "../", default-features = false }
25 changes: 25 additions & 0 deletions ffi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use core::slice;

#[no_mangle]
pub unsafe extern "C" fn gxhash0_32(buf: *const (), len: usize, seed: i32) -> u32 {
let data: &[u8] = slice::from_raw_parts(buf as *const u8, len);
gxhash::gxhash0_32(data, seed)
}

#[no_mangle]
pub unsafe extern "C" fn gxhash0_64(buf: *const (), len: usize, seed: i32) -> u64 {
let data: &[u8] = slice::from_raw_parts(buf as *const u8, len);
gxhash::gxhash0_64(data, seed)
}

#[no_mangle]
pub unsafe extern "C" fn gxhash1_32(buf: *const (), len: usize, seed: i32) -> u32 {
let data: &[u8] = slice::from_raw_parts(buf as *const u8, len);
gxhash::gxhash1_32(data, seed)
}

#[no_mangle]
pub unsafe extern "C" fn gxhash1_64(buf: *const (), len: usize, seed: i32) -> u64 {
let data: &[u8] = slice::from_raw_parts(buf as *const u8, len);
gxhash::gxhash1_64(data, seed)
}
Loading
Loading