Skip to content

Instantly share code, notes, and snippets.

@ArtemGr
Last active January 28, 2018 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArtemGr/cc1707311a4fa1d5fde30d554d9fb5e3 to your computer and use it in GitHub Desktop.
Save ArtemGr/cc1707311a4fa1d5fde30d554d9fb5e3 to your computer and use it in GitHub Desktop.
Inline hex escape
# 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
[package]
name = "hex"
version = "0.1.0"
[dependencies]
fomat-macros = "*"
#![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