Last active
January 28, 2018 12:08
-
-
Save ArtemGr/cc1707311a4fa1d5fde30d554d9fb5e3 to your computer and use it in GitHub Desktop.
Inline hex escape
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz | |
$ RUSTFLAGS='-C target-cpu=native' cargo bench | |
test bench_specialized_hex_push ... bench: 12 ns/iter (+/- 0) = 250 MB/s | |
test bench_specialized_fomat ... bench: 42 ns/iter (+/- 12) = 71 MB/s | |
test bench_specialized_format ... bench: 47 ns/iter (+/- 2) = 63 MB/s | |
test bench_specialized_hex_string ... bench: 76 ns/iter (+/- 9) = 39 MB/s | |
test bench_to_hex ... bench: 82 ns/iter (+/- 12) = 36 MB/s | |
test bench_format ... bench: 97 ns/iter (+/- 8) = 30 MB/s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "hex" | |
version = "0.1.0" | |
[dependencies] | |
fomat-macros = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(test, rustc_private)] | |
#[macro_use] | |
extern crate fomat_macros; | |
extern crate rustc_serialize; | |
extern crate test; | |
use rustc_serialize::hex::ToHex; | |
use std::fmt; | |
use test::Bencher; | |
pub fn hex_string(blob: &[u8]) -> String { | |
let mut buf = String::with_capacity(blob.len() * 2); | |
hex_push(&mut buf, blob); | |
buf | |
} | |
fn hex_from_digit(num: u8) -> char { | |
if num < 10 { | |
(b'0' + num) as char | |
} else { | |
(b'A' + num - 10) as char | |
} | |
} | |
pub fn hex_push(buf: &mut String, blob: &[u8]) { | |
for ch in blob { | |
buf.push(hex_from_digit(ch / 16)); | |
buf.push(hex_from_digit(ch % 16)) | |
} | |
} | |
pub struct Hex<'a>(&'a [u8]); | |
impl<'a> fmt::Display for Hex<'a> { | |
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
use fmt::Write; | |
for ch in self.0 { | |
f.write_char(hex_from_digit(ch / 16))?; | |
f.write_char(hex_from_digit(ch % 16))?; | |
} | |
Ok(()) | |
} | |
} | |
#[bench] | |
fn bench_specialized_hex_string(b: &mut Bencher) { | |
b.bytes = 3; | |
b.iter(|| { | |
assert_eq!(hex_string(b"123"), "313233"); | |
}); | |
} | |
#[bench] | |
fn bench_specialized_hex_push(b: &mut Bencher) { | |
let mut buf = String::with_capacity(6); | |
b.bytes = 3; | |
b.iter(|| { | |
buf.clear(); | |
hex_push(&mut buf, b"123"); | |
assert_eq!(buf, "313233"); | |
}); | |
} | |
#[bench] | |
fn bench_to_hex(b: &mut Bencher) { | |
b.bytes = 3; | |
b.iter(|| { | |
assert_eq!(b"123".to_hex(), "313233"); | |
}); | |
} | |
#[bench] | |
fn bench_format(b: &mut Bencher) { | |
use std::fmt::Write; | |
let mut buf = String::with_capacity(6); | |
b.bytes = 3; | |
b.iter(|| { | |
buf.clear(); | |
for ch in b"123" { | |
let _ = write!(&mut buf, "{:x}", ch); | |
} | |
assert_eq!(buf, "313233"); | |
}); | |
} | |
#[bench] | |
fn bench_specialized_format(b: &mut Bencher) { | |
use std::fmt::Write; | |
let mut buf = String::with_capacity(6); | |
b.bytes = 3; | |
b.iter(|| { | |
buf.clear(); | |
let _ = write!(&mut buf, "{}", Hex(b"123")); | |
assert_eq!(buf, "313233"); | |
}); | |
} | |
#[bench] | |
fn bench_specialized_fomat(b: &mut Bencher) { | |
use std::fmt::Write; | |
let mut buf = String::with_capacity(6); | |
b.bytes = 3; | |
b.iter(|| { | |
buf.clear(); | |
let _ = wite!(&mut buf, (Hex(b"123"))); | |
assert_eq!(buf, "313233"); | |
}); | |
} | |
fn main() { | |
println!("{}", hex_string(b"123")); | |
println!("{}", hex_string("про".as_bytes())); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment