Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: DaniPopes/const-hex
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.11.3
Choose a base ref
...
head repository: DaniPopes/const-hex
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.12.0
Choose a head ref
  • 5 commits
  • 11 files changed
  • 3 contributors

Commits on Mar 13, 2024

  1. test: check empty strings

    DaniPopes committed Mar 13, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    b055b1e View commit details

Commits on May 15, 2024

  1. Derive Eq trait for FromHexError (#9)

    Without this we cannot derive Eq on enums & structs that contain a
    FromHexError. It is trivial to derive since all the elements of
    FromHexError implement Eq already
    
    Co-authored-by: James MacAdie (TT sandbox) <[email protected]>
    jmacadie and James MacAdie (TT sandbox) authored May 15, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    7ceae26 View commit details
  2. chore: Release const-hex version 1.11.4

    DaniPopes committed May 15, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    a3944b6 View commit details

Commits on May 27, 2024

  1. feat: implement check for arm and portable-simd (#10)

    DaniPopes authored May 27, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    378861a View commit details
  2. chore: Release const-hex version 1.12.0

    DaniPopes committed May 27, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    c81503c View commit details
Showing with 253 additions and 146 deletions.
  1. +4 −6 .github/workflows/ci.yml
  2. +1 −1 Cargo.toml
  3. +108 −89 README.md
  4. +44 −0 benches/bench/main.rs
  5. +40 −2 src/arch/aarch64.rs
  6. +5 −6 src/arch/generic.rs
  7. +22 −8 src/arch/portable_simd.rs
  8. +24 −32 src/arch/x86.rs
  9. +1 −1 src/error.rs
  10. +1 −1 src/lib.rs
  11. +3 −0 tests/test.rs
10 changes: 4 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -40,11 +40,11 @@ jobs:
- uses: Swatinem/rust-cache@v2

- run: cargo build
- run: cargo test
- run: cargo build --no-default-features
- run: cargo test --tests --no-default-features
- run: cargo test --tests --no-default-features --features force-generic
- run: cargo test --tests --no-default-features --features nightly,portable-simd
- run: cargo test
- run: cargo test --no-default-features
- run: cargo test --no-default-features --features force-generic
- run: cargo test --no-default-features --features nightly,portable-simd
if: matrix.rust == 'nightly'
- run: cargo bench --no-run
if: matrix.rust == 'nightly'
@@ -65,8 +65,6 @@ jobs:
- uses: dtolnay/rust-toolchain@miri
with:
target: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- run: cargo miri setup --target ${{ matrix.target }} ${{ matrix.flags }}
- run: cargo miri test --target ${{ matrix.target }} ${{ matrix.flags }}

fuzz:
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "const-hex"
version = "1.11.3"
version = "1.12.0"
authors = ["DaniPopes <57450786+DaniPopes@users.noreply.github.com>"]
description = "Fast byte array to hex string conversion"
edition = "2021"
197 changes: 108 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
@@ -27,100 +27,119 @@ This crate is 10 to 50 times faster than [`hex`] in encoding and decoding, and
100+ times faster than `libstd` in formatting.

The following benchmarks were ran on an AMD Ryzen 9 7950X, compiled with
`1.78.0-nightly (a4472498d 2024-02-15)` on `x86_64-unknown-linux-gnu`.
`1.80.0-nightly (bdbbb6c6a 2024-05-26)` on `x86_64-unknown-linux-gnu`.

You can run these benchmarks with `cargo bench --features std` on a nightly
compiler.

```log
test decode::const_hex::bench1_32b ... bench: 16 ns/iter (+/- 5)
test decode::const_hex::bench2_256b ... bench: 37 ns/iter (+/- 0)
test decode::const_hex::bench3_2k ... bench: 232 ns/iter (+/- 2)
test decode::const_hex::bench4_16k ... bench: 1,672 ns/iter (+/- 12)
test decode::const_hex::bench5_128k ... bench: 12,979 ns/iter (+/- 91)
test decode::const_hex::bench6_1m ... bench: 104,751 ns/iter (+/- 2,068)
test decode::faster_hex::bench1_32b ... bench: 15 ns/iter (+/- 0)
test decode::faster_hex::bench2_256b ... bench: 54 ns/iter (+/- 1)
test decode::faster_hex::bench3_2k ... bench: 253 ns/iter (+/- 3)
test decode::faster_hex::bench4_16k ... bench: 1,831 ns/iter (+/- 20)
test decode::faster_hex::bench5_128k ... bench: 14,120 ns/iter (+/- 57)
test decode::faster_hex::bench6_1m ... bench: 115,291 ns/iter (+/- 1,325)
test decode::hex::bench1_32b ... bench: 104 ns/iter (+/- 1)
test decode::hex::bench2_256b ... bench: 697 ns/iter (+/- 7)
test decode::hex::bench3_2k ... bench: 5,189 ns/iter (+/- 86)
test decode::hex::bench4_16k ... bench: 42,355 ns/iter (+/- 21,853)
test decode::hex::bench5_128k ... bench: 765,278 ns/iter (+/- 4,091)
test decode::hex::bench6_1m ... bench: 6,161,416 ns/iter (+/- 64,954)
test decode_to_slice::const_hex::bench1_32b ... bench: 5 ns/iter (+/- 0)
test decode_to_slice::const_hex::bench2_256b ... bench: 26 ns/iter (+/- 0)
test decode_to_slice::const_hex::bench3_2k ... bench: 210 ns/iter (+/- 10)
test decode_to_slice::const_hex::bench4_16k ... bench: 1,667 ns/iter (+/- 13)
test decode_to_slice::const_hex::bench5_128k ... bench: 13,043 ns/iter (+/- 19)
test decode_to_slice::const_hex::bench6_1m ... bench: 105,883 ns/iter (+/- 1,427)
test decode_to_slice::faster_hex::bench1_32b ... bench: 6 ns/iter (+/- 0)
test decode_to_slice::faster_hex::bench2_256b ... bench: 28 ns/iter (+/- 0)
test decode_to_slice::faster_hex::bench3_2k ... bench: 214 ns/iter (+/- 2)
test decode_to_slice::faster_hex::bench4_16k ... bench: 1,710 ns/iter (+/- 6)
test decode_to_slice::faster_hex::bench5_128k ... bench: 13,304 ns/iter (+/- 37)
test decode_to_slice::faster_hex::bench6_1m ... bench: 110,276 ns/iter (+/- 3,475)
test decode_to_slice::hex::bench1_32b ... bench: 38 ns/iter (+/- 2)
test decode_to_slice::hex::bench2_256b ... bench: 300 ns/iter (+/- 185)
test decode_to_slice::hex::bench3_2k ... bench: 2,717 ns/iter (+/- 64)
test decode_to_slice::hex::bench4_16k ... bench: 19,257 ns/iter (+/- 530)
test decode_to_slice::hex::bench5_128k ... bench: 624,172 ns/iter (+/- 15,725)
test decode_to_slice::hex::bench6_1m ... bench: 5,333,915 ns/iter (+/- 298,093)
test encode::const_hex::bench1_32b ... bench: 6 ns/iter (+/- 0)
test encode::const_hex::bench2_256b ... bench: 10 ns/iter (+/- 0)
test encode::const_hex::bench3_2k ... bench: 72 ns/iter (+/- 1)
test encode::const_hex::bench4_16k ... bench: 462 ns/iter (+/- 4)
test encode::const_hex::bench5_128k ... bench: 3,600 ns/iter (+/- 28)
test encode::const_hex::bench6_1m ... bench: 29,447 ns/iter (+/- 858)
test encode::faster_hex::bench1_32b ... bench: 17 ns/iter (+/- 0)
test encode::faster_hex::bench2_256b ... bench: 37 ns/iter (+/- 3)
test encode::faster_hex::bench3_2k ... bench: 102 ns/iter (+/- 1)
test encode::faster_hex::bench4_16k ... bench: 614 ns/iter (+/- 6)
test encode::faster_hex::bench5_128k ... bench: 4,764 ns/iter (+/- 12)
test encode::faster_hex::bench6_1m ... bench: 40,894 ns/iter (+/- 1,223)
test encode::hex::bench1_32b ... bench: 112 ns/iter (+/- 0)
test encode::hex::bench2_256b ... bench: 812 ns/iter (+/- 5)
test encode::hex::bench3_2k ... bench: 6,404 ns/iter (+/- 26)
test encode::hex::bench4_16k ... bench: 51,039 ns/iter (+/- 595)
test encode::hex::bench5_128k ... bench: 408,378 ns/iter (+/- 23,022)
test encode::hex::bench6_1m ... bench: 3,571,916 ns/iter (+/- 142,828)
test encode_to_slice::const_hex::bench1_32b ... bench: 1 ns/iter (+/- 0)
test encode_to_slice::const_hex::bench2_256b ... bench: 6 ns/iter (+/- 0)
test encode_to_slice::const_hex::bench3_2k ... bench: 53 ns/iter (+/- 0)
test encode_to_slice::const_hex::bench4_16k ... bench: 452 ns/iter (+/- 3)
test encode_to_slice::const_hex::bench5_128k ... bench: 3,550 ns/iter (+/- 10)
test encode_to_slice::const_hex::bench6_1m ... bench: 29,605 ns/iter (+/- 916)
test encode_to_slice::faster_hex::bench1_32b ... bench: 4 ns/iter (+/- 0)
test encode_to_slice::faster_hex::bench2_256b ... bench: 7 ns/iter (+/- 0)
test encode_to_slice::faster_hex::bench3_2k ... bench: 47 ns/iter (+/- 0)
test encode_to_slice::faster_hex::bench4_16k ... bench: 402 ns/iter (+/- 5)
test encode_to_slice::faster_hex::bench5_128k ... bench: 3,121 ns/iter (+/- 25)
test encode_to_slice::faster_hex::bench6_1m ... bench: 26,171 ns/iter (+/- 573)
test encode_to_slice::hex::bench1_32b ... bench: 11 ns/iter (+/- 0)
test encode_to_slice::hex::bench2_256b ... bench: 118 ns/iter (+/- 0)
test encode_to_slice::hex::bench3_2k ... bench: 994 ns/iter (+/- 4)
test encode_to_slice::hex::bench4_16k ... bench: 8,065 ns/iter (+/- 31)
test encode_to_slice::hex::bench5_128k ... bench: 63,982 ns/iter (+/- 2,026)
test encode_to_slice::hex::bench6_1m ... bench: 515,171 ns/iter (+/- 2,789)
test format::const_hex::bench1_32b ... bench: 9 ns/iter (+/- 0)
test format::const_hex::bench2_256b ... bench: 18 ns/iter (+/- 0)
test format::const_hex::bench3_2k ... bench: 119 ns/iter (+/- 1)
test format::const_hex::bench4_16k ... bench: 1,157 ns/iter (+/- 3)
test format::const_hex::bench5_128k ... bench: 9,560 ns/iter (+/- 443)
test format::const_hex::bench6_1m ... bench: 85,479 ns/iter (+/- 1,498)
test format::std::bench1_32b ... bench: 374 ns/iter (+/- 6)
test format::std::bench2_256b ... bench: 2,952 ns/iter (+/- 10)
test format::std::bench3_2k ... bench: 23,767 ns/iter (+/- 61)
test format::std::bench4_16k ... bench: 183,579 ns/iter (+/- 2,078)
test format::std::bench5_128k ... bench: 1,498,391 ns/iter (+/- 8,445)
test format::std::bench6_1m ... bench: 11,965,082 ns/iter (+/- 43,784)
test check::const_hex::bench1_32b ... bench: 9.79 ns/iter (+/- 2.22)
test check::const_hex::bench2_256b ... bench: 20.22 ns/iter (+/- 6.41)
test check::const_hex::bench3_2k ... bench: 124.57 ns/iter (+/- 9.68)
test check::const_hex::bench4_16k ... bench: 927.53 ns/iter (+/- 81.94)
test check::const_hex::bench5_128k ... bench: 7,300.16 ns/iter (+/- 153.57)
test check::const_hex::bench6_1m ... bench: 59,886.62 ns/iter (+/- 1,312.15)
test check::faster_hex::bench1_32b ... bench: 2.93 ns/iter (+/- 0.20)
test check::faster_hex::bench2_256b ... bench: 15.54 ns/iter (+/- 0.77)
test check::faster_hex::bench3_2k ... bench: 121.17 ns/iter (+/- 0.70)
test check::faster_hex::bench4_16k ... bench: 945.17 ns/iter (+/- 12.48)
test check::faster_hex::bench5_128k ... bench: 7,632.07 ns/iter (+/- 172.68)
test check::faster_hex::bench6_1m ... bench: 61,427.03 ns/iter (+/- 732.21)
test check::naive::bench1_32b ... bench: 26.15 ns/iter (+/- 1.04)
test check::naive::bench2_256b ... bench: 225.69 ns/iter (+/- 9.02)
test check::naive::bench3_2k ... bench: 1,952.05 ns/iter (+/- 20.46)
test check::naive::bench4_16k ... bench: 20,329.63 ns/iter (+/- 455.31)
test check::naive::bench5_128k ... bench: 503,460.10 ns/iter (+/- 8,930.00)
test check::naive::bench6_1m ... bench: 4,252,331.00 ns/iter (+/- 191,519.79)
test decode::const_hex::bench1_32b ... bench: 19.49 ns/iter (+/- 0.82)
test decode::const_hex::bench2_256b ... bench: 41.47 ns/iter (+/- 1.45)
test decode::const_hex::bench3_2k ... bench: 236.69 ns/iter (+/- 2.75)
test decode::const_hex::bench4_16k ... bench: 1,682.25 ns/iter (+/- 18.07)
test decode::const_hex::bench5_128k ... bench: 13,096.94 ns/iter (+/- 138.05)
test decode::const_hex::bench6_1m ... bench: 105,360.67 ns/iter (+/- 2,771.85)
test decode::faster_hex::bench1_32b ... bench: 16.49 ns/iter (+/- 0.12)
test decode::faster_hex::bench2_256b ... bench: 54.92 ns/iter (+/- 1.74)
test decode::faster_hex::bench3_2k ... bench: 246.11 ns/iter (+/- 3.25)
test decode::faster_hex::bench4_16k ... bench: 1,839.88 ns/iter (+/- 22.36)
test decode::faster_hex::bench5_128k ... bench: 14,376.52 ns/iter (+/- 203.97)
test decode::faster_hex::bench6_1m ... bench: 116,345.50 ns/iter (+/- 1,377.06)
test decode::hex::bench1_32b ... bench: 101.38 ns/iter (+/- 3.41)
test decode::hex::bench2_256b ... bench: 655.85 ns/iter (+/- 17.69)
test decode::hex::bench3_2k ... bench: 4,830.90 ns/iter (+/- 73.58)
test decode::hex::bench4_16k ... bench: 37,976.46 ns/iter (+/- 443.65)
test decode::hex::bench5_128k ... bench: 734,983.30 ns/iter (+/- 4,297.49)
test decode::hex::bench6_1m ... bench: 5,901,860.30 ns/iter (+/- 22,806.40)
test decode_to_slice::const_hex::bench1_32b ... bench: 11.03 ns/iter (+/- 0.50)
test decode_to_slice::const_hex::bench2_256b ... bench: 28.93 ns/iter (+/- 1.38)
test decode_to_slice::const_hex::bench3_2k ... bench: 210.49 ns/iter (+/- 5.65)
test decode_to_slice::const_hex::bench4_16k ... bench: 1,670.55 ns/iter (+/- 17.87)
test decode_to_slice::const_hex::bench5_128k ... bench: 13,094.65 ns/iter (+/- 115.89)
test decode_to_slice::const_hex::bench6_1m ... bench: 105,036.12 ns/iter (+/- 1,722.56)
test decode_to_slice::faster_hex::bench1_32b ... bench: 6.26 ns/iter (+/- 0.10)
test decode_to_slice::faster_hex::bench2_256b ... bench: 28.73 ns/iter (+/- 0.55)
test decode_to_slice::faster_hex::bench3_2k ... bench: 213.70 ns/iter (+/- 2.83)
test decode_to_slice::faster_hex::bench4_16k ... bench: 1,718.21 ns/iter (+/- 23.97)
test decode_to_slice::faster_hex::bench5_128k ... bench: 13,530.96 ns/iter (+/- 97.41)
test decode_to_slice::faster_hex::bench6_1m ... bench: 107,708.79 ns/iter (+/- 1,425.58)
test decode_to_slice::hex::bench1_32b ... bench: 39.07 ns/iter (+/- 1.85)
test decode_to_slice::hex::bench2_256b ... bench: 311.73 ns/iter (+/- 10.92)
test decode_to_slice::hex::bench3_2k ... bench: 2,515.69 ns/iter (+/- 63.09)
test decode_to_slice::hex::bench4_16k ... bench: 20,899.92 ns/iter (+/- 442.95)
test decode_to_slice::hex::bench5_128k ... bench: 634,859.00 ns/iter (+/- 6,609.09)
test decode_to_slice::hex::bench6_1m ... bench: 5,338,354.20 ns/iter (+/- 51,493.30)
test encode::const_hex::bench1_32b ... bench: 6.92 ns/iter (+/- 0.11)
test encode::const_hex::bench2_256b ... bench: 11.41 ns/iter (+/- 0.14)
test encode::const_hex::bench3_2k ... bench: 73.59 ns/iter (+/- 1.52)
test encode::const_hex::bench4_16k ... bench: 461.00 ns/iter (+/- 5.17)
test encode::const_hex::bench5_128k ... bench: 3,527.28 ns/iter (+/- 46.86)
test encode::const_hex::bench6_1m ... bench: 29,402.78 ns/iter (+/- 1,032.91)
test encode::faster_hex::bench1_32b ... bench: 17.30 ns/iter (+/- 0.30)
test encode::faster_hex::bench2_256b ... bench: 39.07 ns/iter (+/- 0.73)
test encode::faster_hex::bench3_2k ... bench: 102.93 ns/iter (+/- 1.92)
test encode::faster_hex::bench4_16k ... bench: 651.65 ns/iter (+/- 1.55)
test encode::faster_hex::bench5_128k ... bench: 5,074.50 ns/iter (+/- 22.97)
test encode::faster_hex::bench6_1m ... bench: 46,227.11 ns/iter (+/- 945.52)
test encode::hex::bench1_32b ... bench: 100.46 ns/iter (+/- 0.93)
test encode::hex::bench2_256b ... bench: 717.75 ns/iter (+/- 5.91)
test encode::hex::bench3_2k ... bench: 5,660.67 ns/iter (+/- 246.73)
test encode::hex::bench4_16k ... bench: 44,981.79 ns/iter (+/- 340.51)
test encode::hex::bench5_128k ... bench: 359,401.72 ns/iter (+/- 1,689.97)
test encode::hex::bench6_1m ... bench: 2,966,947.20 ns/iter (+/- 165,738.51)
test encode_to_slice::const_hex::bench1_32b ... bench: 1.55 ns/iter (+/- 0.04)
test encode_to_slice::const_hex::bench2_256b ... bench: 6.73 ns/iter (+/- 0.08)
test encode_to_slice::const_hex::bench3_2k ... bench: 54.23 ns/iter (+/- 2.06)
test encode_to_slice::const_hex::bench4_16k ... bench: 471.90 ns/iter (+/- 21.13)
test encode_to_slice::const_hex::bench5_128k ... bench: 3,730.44 ns/iter (+/- 113.80)
test encode_to_slice::const_hex::bench6_1m ... bench: 29,247.93 ns/iter (+/- 926.38)
test encode_to_slice::faster_hex::bench1_32b ... bench: 3.95 ns/iter (+/- 0.26)
test encode_to_slice::faster_hex::bench2_256b ... bench: 7.49 ns/iter (+/- 0.47)
test encode_to_slice::faster_hex::bench3_2k ... bench: 48.56 ns/iter (+/- 1.95)
test encode_to_slice::faster_hex::bench4_16k ... bench: 424.65 ns/iter (+/- 11.39)
test encode_to_slice::faster_hex::bench5_128k ... bench: 3,317.47 ns/iter (+/- 103.44)
test encode_to_slice::faster_hex::bench6_1m ... bench: 26,079.18 ns/iter (+/- 889.52)
test encode_to_slice::hex::bench1_32b ... bench: 11.99 ns/iter (+/- 0.30)
test encode_to_slice::hex::bench2_256b ... bench: 119.07 ns/iter (+/- 2.85)
test encode_to_slice::hex::bench3_2k ... bench: 999.68 ns/iter (+/- 26.35)
test encode_to_slice::hex::bench4_16k ... bench: 8,049.82 ns/iter (+/- 105.51)
test encode_to_slice::hex::bench5_128k ... bench: 65,186.25 ns/iter (+/- 758.98)
test encode_to_slice::hex::bench6_1m ... bench: 511,447.00 ns/iter (+/- 4,866.41)
test format::const_hex::bench1_32b ... bench: 9.84 ns/iter (+/- 0.21)
test format::const_hex::bench2_256b ... bench: 17.90 ns/iter (+/- 0.55)
test format::const_hex::bench3_2k ... bench: 119.47 ns/iter (+/- 3.87)
test format::const_hex::bench4_16k ... bench: 1,161.94 ns/iter (+/- 20.11)
test format::const_hex::bench5_128k ... bench: 9,580.23 ns/iter (+/- 188.10)
test format::const_hex::bench6_1m ... bench: 84,316.47 ns/iter (+/- 1,407.10)
test format::std::bench1_32b ... bench: 371.37 ns/iter (+/- 3.63)
test format::std::bench2_256b ... bench: 2,987.01 ns/iter (+/- 41.26)
test format::std::bench3_2k ... bench: 23,989.24 ns/iter (+/- 373.84)
test format::std::bench4_16k ... bench: 192,881.92 ns/iter (+/- 9,266.64)
test format::std::bench5_128k ... bench: 1,554,062.80 ns/iter (+/- 10,998.30)
test format::std::bench6_1m ... bench: 12,378,548.00 ns/iter (+/- 247,626.30)
```

## Acknowledgements
44 changes: 44 additions & 0 deletions benches/bench/main.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,50 @@ impl<const N: usize> fmt::Display for StdFormat<N> {

macro_rules! benches {
($($name:ident($enc:expr, $dec:expr))*) => {
mod check {
use super::*;

mod const_hex {
use super::*;

$(
#[bench]
fn $name(b: &mut Bencher) {
b.iter(|| {
::const_hex::check(black_box($dec))
});
}
)*
}

mod faster_hex {
use super::*;

$(
#[bench]
fn $name(b: &mut Bencher) {
b.iter(|| {
::faster_hex::hex_check(black_box($dec.as_bytes()))
});
}
)*
}

mod naive {
use super::*;

$(
#[bench]
fn $name(b: &mut Bencher) {
b.iter(|| {
let dec = black_box($dec.as_bytes());
dec.iter().all(u8::is_ascii_hexdigit)
});
}
)*
}
}

#[cfg(feature = "alloc")]
mod decode {
use super::*;
Loading