const-hex

Fast byte array to hex string conversion

APACHE-2.0 License

Downloads
4.1M
Stars
22

const-hex

This crate provides a fast conversion of byte arrays to hexadecimal strings, both at compile time, and at run time.

It aims to be a drop-in replacement for the hex crate, as well as extending the API with const-eval, a const-generics formatting buffer, similar to itoa's, and more.

Version requirement: rustc 1.64+

Performance

This crate offers performance comparable to faster-hex on x86/x86-64 architectures but outperforms it on other platforms, as faster-hex is only optimized for x86/x86-64.

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.83.0-nightly (9e394f551 2024-09-25) on x86_64-unknown-linux-gnu.

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

test check::const_hex::bench1_32b             ... bench:           2.85 ns/iter (+/- 0.44)
test check::const_hex::bench2_256b            ... bench:          15.36 ns/iter (+/- 0.44)
test check::const_hex::bench3_2k              ... bench:         117.55 ns/iter (+/- 1.72)
test check::const_hex::bench4_16k             ... bench:         915.78 ns/iter (+/- 56.34)
test check::const_hex::bench5_128k            ... bench:       7,269.26 ns/iter (+/- 80.62)
test check::const_hex::bench6_1m              ... bench:      58,975.63 ns/iter (+/- 707.02)
test check::faster_hex::bench1_32b            ... bench:           2.70 ns/iter (+/- 0.01)
test check::faster_hex::bench2_256b           ... bench:          14.45 ns/iter (+/- 1.44)
test check::faster_hex::bench3_2k             ... bench:         123.58 ns/iter (+/- 1.09)
test check::faster_hex::bench4_16k            ... bench:         960.32 ns/iter (+/- 6.34)
test check::faster_hex::bench5_128k           ... bench:       7,709.14 ns/iter (+/- 77.69)
test check::faster_hex::bench6_1m             ... bench:      62,165.54 ns/iter (+/- 1,167.78)
test check::naive::bench1_32b                 ... bench:          16.41 ns/iter (+/- 1.90)
test check::naive::bench2_256b                ... bench:         221.25 ns/iter (+/- 3.47)
test check::naive::bench3_2k                  ... bench:       2,493.23 ns/iter (+/- 154.04)
test check::naive::bench4_16k                 ... bench:      16,221.81 ns/iter (+/- 384.98)
test check::naive::bench5_128k                ... bench:     485,588.59 ns/iter (+/- 10,260.00)
test check::naive::bench6_1m                  ... bench:   3,895,089.20 ns/iter (+/- 45,589.05)

test decode::const_hex::bench1_32b            ... bench:          17.33 ns/iter (+/- 0.38)
test decode::const_hex::bench2_256b           ... bench:          38.17 ns/iter (+/- 1.07)
test decode::const_hex::bench3_2k             ... bench:         235.07 ns/iter (+/- 3.27)
test decode::const_hex::bench4_16k            ... bench:       1,681.14 ns/iter (+/- 17.25)
test decode::const_hex::bench5_128k           ... bench:      13,097.65 ns/iter (+/- 101.14)
test decode::const_hex::bench6_1m             ... bench:     105,945.60 ns/iter (+/- 2,703.49)
test decode::faster_hex::bench1_32b           ... bench:          17.91 ns/iter (+/- 0.40)
test decode::faster_hex::bench2_256b          ... bench:          54.53 ns/iter (+/- 1.41)
test decode::faster_hex::bench3_2k            ... bench:         245.35 ns/iter (+/- 3.89)
test decode::faster_hex::bench4_16k           ... bench:       1,836.62 ns/iter (+/- 25.01)
test decode::faster_hex::bench5_128k          ... bench:      14,471.53 ns/iter (+/- 184.29)
test decode::faster_hex::bench6_1m            ... bench:     116,688.27 ns/iter (+/- 1,539.72)
test decode::hex::bench1_32b                  ... bench:         109.14 ns/iter (+/- 1.88)
test decode::hex::bench2_256b                 ... bench:         712.92 ns/iter (+/- 14.25)
test decode::hex::bench3_2k                   ... bench:       5,196.66 ns/iter (+/- 102.67)
test decode::hex::bench4_16k                  ... bench:      41,308.30 ns/iter (+/- 917.60)
test decode::hex::bench5_128k                 ... bench:     786,648.00 ns/iter (+/- 6,589.60)
test decode::hex::bench6_1m                   ... bench:   6,316,271.50 ns/iter (+/- 22,712.18)

test decode_to_slice::const_hex::bench1_32b   ... bench:           5.14 ns/iter (+/- 0.39)
test decode_to_slice::const_hex::bench2_256b  ... bench:          26.18 ns/iter (+/- 0.26)
test decode_to_slice::const_hex::bench3_2k    ... bench:         206.71 ns/iter (+/- 1.88)
test decode_to_slice::const_hex::bench4_16k   ... bench:       1,666.49 ns/iter (+/- 15.67)
test decode_to_slice::const_hex::bench5_128k  ... bench:      12,979.03 ns/iter (+/- 80.40)
test decode_to_slice::const_hex::bench6_1m    ... bench:     107,213.20 ns/iter (+/- 4,024.91)
test decode_to_slice::faster_hex::bench1_32b  ... bench:           6.51 ns/iter (+/- 0.04)
test decode_to_slice::faster_hex::bench2_256b ... bench:          28.66 ns/iter (+/- 0.29)
test decode_to_slice::faster_hex::bench3_2k   ... bench:         217.84 ns/iter (+/- 1.03)
test decode_to_slice::faster_hex::bench4_16k  ... bench:       1,730.89 ns/iter (+/- 19.36)
test decode_to_slice::faster_hex::bench5_128k ... bench:      13,439.63 ns/iter (+/- 92.19)
test decode_to_slice::faster_hex::bench6_1m   ... bench:     109,432.90 ns/iter (+/- 1,526.01)
test decode_to_slice::hex::bench1_32b         ... bench:          38.44 ns/iter (+/- 1.30)
test decode_to_slice::hex::bench2_256b        ... bench:         290.78 ns/iter (+/- 16.09)
test decode_to_slice::hex::bench3_2k          ... bench:       2,663.51 ns/iter (+/- 48.22)
test decode_to_slice::hex::bench4_16k         ... bench:      19,016.95 ns/iter (+/- 514.35)
test decode_to_slice::hex::bench5_128k        ... bench:     612,840.31 ns/iter (+/- 6,561.70)
test decode_to_slice::hex::bench6_1m          ... bench:   5,098,572.75 ns/iter (+/- 120,113.94)

test encode::const_hex::bench1_32b            ... bench:           6.94 ns/iter (+/- 0.06)
test encode::const_hex::bench2_256b           ... bench:          11.84 ns/iter (+/- 0.07)
test encode::const_hex::bench3_2k             ... bench:          78.36 ns/iter (+/- 0.89)
test encode::const_hex::bench4_16k            ... bench:         475.29 ns/iter (+/- 11.56)
test encode::const_hex::bench5_128k           ... bench:       3,577.27 ns/iter (+/- 70.48)
test encode::const_hex::bench6_1m             ... bench:      29,996.00 ns/iter (+/- 668.44)
test encode::faster_hex::bench1_32b           ... bench:          17.31 ns/iter (+/- 0.37)
test encode::faster_hex::bench2_256b          ... bench:          39.39 ns/iter (+/- 0.76)
test encode::faster_hex::bench3_2k            ... bench:         106.60 ns/iter (+/- 1.41)
test encode::faster_hex::bench4_16k           ... bench:         653.21 ns/iter (+/- 5.40)
test encode::faster_hex::bench5_128k          ... bench:       5,260.68 ns/iter (+/- 88.46)
test encode::faster_hex::bench6_1m            ... bench:      44,520.36 ns/iter (+/- 1,200.74)
test encode::hex::bench1_32b                  ... bench:         102.77 ns/iter (+/- 0.82)
test encode::hex::bench2_256b                 ... bench:         720.90 ns/iter (+/- 22.52)
test encode::hex::bench3_2k                   ... bench:       5,672.44 ns/iter (+/- 287.53)
test encode::hex::bench4_16k                  ... bench:      38,988.71 ns/iter (+/- 6,457.99)
test encode::hex::bench5_128k                 ... bench:     364,376.25 ns/iter (+/- 51,416.85)
test encode::hex::bench6_1m                   ... bench:   2,959,499.88 ns/iter (+/- 410,006.38)

test encode_to_slice::const_hex::bench1_32b   ... bench:           1.56 ns/iter (+/- 0.00)
test encode_to_slice::const_hex::bench2_256b  ... bench:           6.75 ns/iter (+/- 0.03)
test encode_to_slice::const_hex::bench3_2k    ... bench:          58.32 ns/iter (+/- 0.23)
test encode_to_slice::const_hex::bench4_16k   ... bench:         518.24 ns/iter (+/- 4.91)
test encode_to_slice::const_hex::bench5_128k  ... bench:       4,003.77 ns/iter (+/- 28.57)
test encode_to_slice::const_hex::bench6_1m    ... bench:      34,519.64 ns/iter (+/- 656.35)
test encode_to_slice::faster_hex::bench1_32b  ... bench:           4.54 ns/iter (+/- 0.01)
test encode_to_slice::faster_hex::bench2_256b ... bench:           8.11 ns/iter (+/- 0.05)
test encode_to_slice::faster_hex::bench3_2k   ... bench:          52.10 ns/iter (+/- 0.64)
test encode_to_slice::faster_hex::bench4_16k  ... bench:         475.81 ns/iter (+/- 6.50)
test encode_to_slice::faster_hex::bench5_128k ... bench:       3,425.49 ns/iter (+/- 15.01)
test encode_to_slice::faster_hex::bench6_1m   ... bench:      28,725.82 ns/iter (+/- 839.95)
test encode_to_slice::hex::bench1_32b         ... bench:          12.01 ns/iter (+/- 0.12)
test encode_to_slice::hex::bench2_256b        ... bench:         121.68 ns/iter (+/- 1.98)
test encode_to_slice::hex::bench3_2k          ... bench:         989.33 ns/iter (+/- 3.83)
test encode_to_slice::hex::bench4_16k         ... bench:       8,087.93 ns/iter (+/- 25.25)
test encode_to_slice::hex::bench5_128k        ... bench:      64,323.94 ns/iter (+/- 249.97)
test encode_to_slice::hex::bench6_1m          ... bench:     515,710.80 ns/iter (+/- 2,232.59)

test format::const_hex::bench1_32b            ... bench:          10.26 ns/iter (+/- 0.19)
test format::const_hex::bench2_256b           ... bench:          18.28 ns/iter (+/- 0.86)
test format::const_hex::bench3_2k             ... bench:         116.95 ns/iter (+/- 2.17)
test format::const_hex::bench4_16k            ... bench:       1,122.29 ns/iter (+/- 6.25)
test format::const_hex::bench5_128k           ... bench:       8,903.81 ns/iter (+/- 111.29)
test format::const_hex::bench6_1m             ... bench:      77,476.15 ns/iter (+/- 1,498.93)
test format::std::bench1_32b                  ... bench:         370.27 ns/iter (+/- 2.52)
test format::std::bench2_256b                 ... bench:       2,910.66 ns/iter (+/- 40.35)
test format::std::bench3_2k                   ... bench:      22,554.52 ns/iter (+/- 263.93)
test format::std::bench4_16k                  ... bench:     182,692.06 ns/iter (+/- 3,494.64)
test format::std::bench5_128k                 ... bench:   1,475,988.90 ns/iter (+/- 21,895.90)
test format::std::bench6_1m                   ... bench:  11,834,234.60 ns/iter (+/- 139,230.20)

Acknowledgements

  • hex for the initial encoding/decoding implementations
  • faster-hex for the x86/x86-64 check and decode implementations
  • dtolnay/itoa for the initial crate/library API layout

License