simd-adler32

A SIMD-accelerated Adler-32 hash algorithm implementation.

## Features

- No dependencies
- Support `no_std` (with `default-features = false`)
- Runtime CPU feature detection (when `std` enabled)
- Blazing fast performance on as many targets as possible (currently only x86 and x86_64)
- Default to scalar implementation when simd not available

## Quick start

> Cargo.toml

```toml
[dependencies]
simd-adler32 = "*"
```

> example.rs

```rust
use simd_adler32::Adler32;

let mut adler = Adler32::new();
adler.write(b"rust is pretty cool, man");
let hash = adler.finish();

println!("{}", hash);
// 1921255656
```

## Support

**CPU Features**

| impl | arch             | feature |
| ---- | ---------------- | ------- |
| ✅   | `x86`, `x86_64`  | avx512  |
| ✅   | `x86`, `x86_64`  | avx2    |
| ✅   | `x86`, `x86_64`  | ssse3   |
| ✅   | `x86`, `x86_64`  | sse2    |
| 🚧   | `arm`, `aarch64` | neon    |
| ✅   | `wasm32`         | simd128 |

**MSRV** `1.36.0`\*\*

Minimum supported rust version is tested before a new version is published. [**] Feature
`const-generics` needs to disabled to build on rustc versions `<1.51` which can be done
by updating your dependency definition to the following.

> Cargo.toml

```toml
[dependencies]
simd-adler32 = { version "*", default-features = false, features = ["std"] }
```

## Performance

Benchmarks listed display number of randomly generated bytes (10k / 100k) and library
name. Benchmarks sources can be found under the [bench](/bench) directory. Crates used for
comparison are [adler](https://crates.io/crates/adler) and
[adler32](https://crates.io/crates/adler32).

> Windows 10 Pro - Intel i5-8300H @ 2.30GHz

| name                    | avg. time       | avg. thrpt         |
| ----------------------- | --------------- | ------------------ |
| **10k/simd-adler32**    | **212.61 ns**   | **43.805 GiB/s**   |
| 10k/wuffs               | 3843 ns         | 2.63 GiB/s\*       |
| 10k/adler32             | 4.8084 us       | 1.9369 GiB/s       |
| 10k/adler               | 17.979 us       | 530.43 MiB/s       |
| ----------------------- | --------------- | ------------------ |
| **100k/simd-adler32**   | **2.7951 us**   | **33.320 GiB/s**   |
| 100k/wuffs              | 34733 ns        | 2.6814 GiB/s\*     |
| 100k/adler32            | 48.488 us       | 1.9207 GiB/s       |
| 100k/adler              | 178.36 us       | 534.69 MiB/s       |

\* wuffs ran using mingw64/gcc, ran with `wuffs bench -ccompilers=gcc -reps=1 -iterscale=300 std/adler32`.

> MacBookPro16,1 - Intel i9-9880H CPU @ 2.30GHz

| name                    | avg. time       | avg. thrpt         |
| ----------------------- | --------------- | ------------------ |
| **10k/simd-adler32**    | **200.37 ns**   | **46.480 GiB/s**   |
| 10k/adler32             | 4.1516 us       | 2.2433 GiB/s       |
| 10k/adler               | 10.220 us       | 933.15 MiB/s       |
| ----------------------- | --------------- | ------------------ |
| **100k/simd-adler32**   | **2.3282 us**   | **40.003 GiB/s**   |
| 100k/adler32            | 41.130 us       | 2.2643 GiB/s       |
| 100k/adler              | 83.776 us       | 534.69 MiB/s       |

## Safety

This crate contains a significant amount of `unsafe` code due to the requirement of `unsafe`
for simd intrinsics. Fuzzing is done on release and debug builds prior to publishing via
`afl`. Fuzzy tests can be found under [fuzz](/fuzz) the directory.

## Resources

- [LICENSE](./LICENSE.md) - MIT
- [CHANGELOG](./CHANGELOG.md)

## Credits

Thank you to the contributors of the following projects.

- [adler](https://github.com/jonas-schievink/adler)
- [adler32](https://github.com/remram44/adler32-rs)
- [crc32fast](https://github.com/srijs/rust-crc32fast)
- [wuffs](https://github.com/google/wuffs)
- [chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=762564)
- [zlib](https://zlib.net/)

## Contributing

Feel free to submit a issue or pull request. :smile:
