| #![feature(test)] |
| |
| extern crate base64; |
| extern crate rand; |
| extern crate test; |
| |
| use base64::display; |
| use base64::{decode, decode_config_buf, decode_config_slice, encode, encode_config_buf, |
| encode_config_slice, Config, MIME, STANDARD}; |
| |
| use rand::Rng; |
| use test::Bencher; |
| |
| #[bench] |
| fn encode_3b(b: &mut Bencher) { |
| do_encode_bench(b, 3) |
| } |
| |
| #[bench] |
| fn encode_3b_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 3, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_3b_slice(b: &mut Bencher) { |
| do_encode_bench_slice(b, 3, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_50b(b: &mut Bencher) { |
| do_encode_bench(b, 50) |
| } |
| |
| #[bench] |
| fn encode_50b_display(b: &mut Bencher) { |
| do_encode_bench_display(b, 50) |
| } |
| |
| #[bench] |
| fn encode_50b_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 50, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_50b_slice(b: &mut Bencher) { |
| do_encode_bench_slice(b, 50, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_100b(b: &mut Bencher) { |
| do_encode_bench(b, 100) |
| } |
| |
| #[bench] |
| fn encode_100b_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 100, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_500b(b: &mut Bencher) { |
| do_encode_bench(b, 500) |
| } |
| |
| #[bench] |
| fn encode_500b_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 500, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_500b_reuse_buf_mime(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 500, MIME) |
| } |
| |
| #[bench] |
| fn encode_3kib(b: &mut Bencher) { |
| do_encode_bench(b, 3 * 1024) |
| } |
| |
| #[bench] |
| fn encode_3kib_display(b: &mut Bencher) { |
| do_encode_bench_display(b, 3 * 1024) |
| } |
| |
| #[bench] |
| fn encode_3kib_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 3 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_3kib_slice(b: &mut Bencher) { |
| do_encode_bench_slice(b, 3 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_3kib_reuse_buf_mime(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 3 * 1024, MIME) |
| } |
| |
| #[bench] |
| fn encode_3mib(b: &mut Bencher) { |
| do_encode_bench(b, 3 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn encode_3mib_display(b: &mut Bencher) { |
| do_encode_bench_display(b, 3 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn encode_3mib_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 3 * 1024 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_3mib_slice(b: &mut Bencher) { |
| do_encode_bench_slice(b, 3 * 1024 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_10mib(b: &mut Bencher) { |
| do_encode_bench(b, 10 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn encode_10mib_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 10 * 1024 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_30mib(b: &mut Bencher) { |
| do_encode_bench(b, 30 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn encode_30mib_reuse_buf(b: &mut Bencher) { |
| do_encode_bench_reuse_buf(b, 30 * 1024 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn encode_30mib_slice(b: &mut Bencher) { |
| do_encode_bench_slice(b, 30 * 1024 * 1024, STANDARD) |
| } |
| |
| #[bench] |
| fn decode_3b(b: &mut Bencher) { |
| do_decode_bench(b, 3) |
| } |
| |
| #[bench] |
| fn decode_3b_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 3) |
| } |
| |
| #[bench] |
| fn decode_3b_slice(b: &mut Bencher) { |
| do_decode_bench_slice(b, 3) |
| } |
| |
| #[bench] |
| fn decode_50b(b: &mut Bencher) { |
| do_decode_bench(b, 50) |
| } |
| |
| #[bench] |
| fn decode_50b_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 50) |
| } |
| |
| #[bench] |
| fn decode_50b_slice(b: &mut Bencher) { |
| do_decode_bench_slice(b, 50) |
| } |
| |
| #[bench] |
| fn decode_100b(b: &mut Bencher) { |
| do_decode_bench(b, 100) |
| } |
| |
| #[bench] |
| fn decode_100b_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 100) |
| } |
| |
| #[bench] |
| fn decode_500b(b: &mut Bencher) { |
| do_decode_bench(b, 500) |
| } |
| |
| #[bench] |
| fn decode_500b_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 500) |
| } |
| |
| #[bench] |
| fn decode_3kib(b: &mut Bencher) { |
| do_decode_bench(b, 3 * 1024) |
| } |
| |
| #[bench] |
| fn decode_3kib_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 3 * 1024) |
| } |
| |
| #[bench] |
| fn decode_3kib_slice(b: &mut Bencher) { |
| do_decode_bench_slice(b, 3 * 1024) |
| } |
| |
| #[bench] |
| fn decode_3mib(b: &mut Bencher) { |
| do_decode_bench(b, 3 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_3mib_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 3 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_3mib_slice(b: &mut Bencher) { |
| do_decode_bench_slice(b, 3 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_10mib(b: &mut Bencher) { |
| do_decode_bench(b, 10 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_10mib_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 10 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_30mib(b: &mut Bencher) { |
| do_decode_bench(b, 30 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_30mib_reuse_buf(b: &mut Bencher) { |
| do_decode_bench_reuse_buf(b, 30 * 1024 * 1024) |
| } |
| |
| #[bench] |
| fn decode_30mib_slice(b: &mut Bencher) { |
| do_decode_bench_slice(b, 30 * 1024 * 1024) |
| } |
| |
| fn do_decode_bench(b: &mut Bencher, size: usize) { |
| let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4); |
| fill(&mut v); |
| let encoded = encode(&v); |
| |
| b.bytes = encoded.len() as u64; |
| b.iter(|| { |
| let orig = decode(&encoded); |
| test::black_box(&orig); |
| }); |
| } |
| |
| fn do_decode_bench_reuse_buf(b: &mut Bencher, size: usize) { |
| let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4); |
| fill(&mut v); |
| let encoded = encode(&v); |
| |
| let mut buf = Vec::new(); |
| b.bytes = encoded.len() as u64; |
| b.iter(|| { |
| decode_config_buf(&encoded, STANDARD, &mut buf).unwrap(); |
| test::black_box(&buf); |
| buf.clear(); |
| }); |
| } |
| |
| fn do_decode_bench_slice(b: &mut Bencher, size: usize) { |
| let mut v: Vec<u8> = Vec::with_capacity(size * 3 / 4); |
| fill(&mut v); |
| let encoded = encode(&v); |
| |
| let mut buf = Vec::new(); |
| buf.resize(size, 0); |
| b.bytes = encoded.len() as u64; |
| b.iter(|| { |
| decode_config_slice(&encoded, STANDARD, &mut buf).unwrap(); |
| test::black_box(&buf); |
| }); |
| } |
| |
| fn do_encode_bench(b: &mut Bencher, size: usize) { |
| let mut v: Vec<u8> = Vec::with_capacity(size); |
| fill(&mut v); |
| |
| b.bytes = v.len() as u64; |
| b.iter(|| { |
| let e = encode(&v); |
| test::black_box(&e); |
| }); |
| } |
| |
| fn do_encode_bench_display(b: &mut Bencher, size: usize) { |
| let mut v: Vec<u8> = Vec::with_capacity(size); |
| fill(&mut v); |
| |
| b.bytes = v.len() as u64; |
| b.iter(|| { |
| let e = format!("{}", display::Base64Display::standard(&v)); |
| test::black_box(&e); |
| }); |
| } |
| |
| fn do_encode_bench_reuse_buf(b: &mut Bencher, size: usize, config: Config) { |
| let mut v: Vec<u8> = Vec::with_capacity(size); |
| fill(&mut v); |
| |
| let mut buf = String::new(); |
| |
| b.bytes = v.len() as u64; |
| b.iter(|| { |
| encode_config_buf(&v, config, &mut buf); |
| buf.clear(); |
| }); |
| } |
| |
| fn do_encode_bench_slice(b: &mut Bencher, size: usize, config: Config) { |
| let mut v: Vec<u8> = Vec::with_capacity(size); |
| fill(&mut v); |
| |
| let mut buf = Vec::new(); |
| |
| b.bytes = v.len() as u64; |
| // conservative estimate of encoded size |
| buf.resize(size * 2, 0); |
| b.iter(|| { |
| encode_config_slice(&v, config, &mut buf); |
| }); |
| } |
| |
| fn fill(v: &mut Vec<u8>) { |
| let cap = v.capacity(); |
| // weak randomness is plenty; we just want to not be completely friendly to the branch predictor |
| let mut r = rand::weak_rng(); |
| while v.len() < cap { |
| v.push(r.gen::<u8>()); |
| } |
| } |