KokaKiwi / rust-hex

A basic crate to encode values to hexadecimal representation. Originally extracted from rustc-serialize.
https://crates.io/crates/hex
Apache License 2.0
201 stars 55 forks source link

Add basic benchmarks #14

Closed shepmaster closed 6 years ago

shepmaster commented 6 years ago

I was curious about an alternate solution, so I created a (simple!) benchmark. The alternate wasn't useful, but maybe the benchmark will be for others:

$ cargo +nightly --version
cargo 0.25.0-nightly (a88fbace4 2017-12-29)
$ cargo +nightly bench --features=benchmarks
test bench::a_bench ... bench:      46,120 ns/iter (+/- 2,220) = 245 MB/s
KokaKiwi commented 6 years ago

Oh cool, actually I planned to do some experiment (someday) on how to speed up the encoding and a benchmark would be useful indeed, thanks :)

shepmaster commented 6 years ago

In that case, I might as well show the change I was testing:

diff --git a/src/lib.rs b/src/lib.rs
index c317ee4..e18a95b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -57,11 +57,17 @@ pub trait ToHex {

 impl<T: AsRef<[u8]>> ToHex for T {
     fn write_hex<W: fmt::Write>(&self, w: &mut W) -> fmt::Result {
-        static CHARS: &'static [u8] = b"0123456789abcdef";
+        fn hex_from_digit(num: u8) -> char {
+            if num < 10 {
+                (b'0' + num) as char
+            } else {
+                (b'a' + num - 10) as char
+            }
+        }

-        for &byte in self.as_ref().iter() {
-            w.write_char(CHARS[(byte >>  4) as usize].into())?;
-            w.write_char(CHARS[(byte & 0xf) as usize].into())?;
+        for ch in self.as_ref().iter() {
+            w.write_char(hex_from_digit(ch / 16))?;
+            w.write_char(hex_from_digit(ch % 16))?;
         }

That produced:

$ cargo +nightly bench --features=benchmarks
test bench::a_bench ... bench:      67,781 ns/iter (+/- 8,054) = 168 MB/s
shepmaster commented 6 years ago

I have a feeling that you can somehow use SIMD instructions to really speed up things, once those are stable.

KokaKiwi commented 6 years ago

Hmm yeah that's a thing to test too, maybe behind a feature-gate in the lib I was thinking about the data-encoding crate too, which I have discussed with the author that told me the hex encoding was kind of quick, so I'm planning to look into this as well