Created
October 19, 2016 17:13
-
-
Save alexcrichton/e0f6c59113c79d5a2505ea54c62bd3f5 to your computer and use it in GitHub Desktop.
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
extern crate zstd; | |
extern crate flate2; | |
extern crate xz2; | |
extern crate brotli2; | |
use std::collections::BTreeMap; | |
use std::env; | |
use std::time::Duration; | |
use std::fs::File; | |
use std::io::Read; | |
use std::time::Instant; | |
macro_rules! t { | |
($e:expr) => (match $e { | |
Ok(e) => e, | |
Err(e) => panic!("{} failed with {}", stringify!($e), e), | |
}) | |
} | |
fn main() { | |
let cwd = env::current_dir().unwrap(); | |
let mut algos = BTreeMap::new(); | |
for e in t!(cwd.read_dir()).map(|e| t!(e)) { | |
if e.path().extension().and_then(|s| s.to_str()) != Some("rlib") { | |
continue | |
} | |
let p = t!(e.path().read_dir()) | |
.map(|e| t!(e)) | |
.map(|e| e.path()) | |
.find(|p| p.extension().and_then(|s| s.to_str()) == Some("deflate")) | |
.unwrap(); | |
let mut compressed_contents = Vec::new(); | |
t!(t!(File::open(&p)).read_to_end(&mut compressed_contents)); | |
let mut contents = Vec::new(); | |
t!(flate2::read::DeflateDecoder::new(&compressed_contents[23..]) | |
.read_to_end(&mut contents)); | |
println!("========================================================="); | |
println!("path: {:?}", e.path().file_name()); | |
println!("size: {:?}", contents.len()); | |
for i in 0..10 { | |
let name = format!("xz{}", i); | |
doit(&name, &mut algos, &contents, &mut |contents| { | |
let mut xz = Vec::new(); | |
t!(xz2::read::XzEncoder::new(&contents[..], i).read_to_end(&mut xz)); | |
xz | |
}); | |
} | |
doit("flate fast", &mut algos, &contents, &mut |contents| { | |
let mut flate = Vec::new(); | |
t!(flate2::read::DeflateEncoder::new(&contents[..], | |
flate2::Compression::Fast).read_to_end(&mut flate)); | |
flate | |
}); | |
doit("flate default", &mut algos, &contents, &mut |contents| { | |
let mut flate = Vec::new(); | |
t!(flate2::read::DeflateEncoder::new(&contents[..], | |
flate2::Compression::Default).read_to_end(&mut flate)); | |
flate | |
}); | |
doit("flate best", &mut algos, &contents, &mut |contents| { | |
let mut flate = Vec::new(); | |
t!(flate2::read::DeflateEncoder::new(&contents[..], | |
flate2::Compression::Best).read_to_end(&mut flate)); | |
flate | |
}); | |
for i in 0..10 { | |
let name = format!("brotli{}", i); | |
doit(&name, &mut algos, &contents, &mut |contents| { | |
let mut brotli = Vec::new(); | |
t!(brotli2::read::BrotliEncoder::new(&contents[..], 6).read_to_end(&mut brotli)); | |
brotli | |
}); | |
} | |
for i in 0..10 { | |
let name = format!("zstd{}", i); | |
doit(&name, &mut algos, &contents, &mut |contents| { | |
zstd::stream::encode_all(&contents[..], i).unwrap() | |
}); | |
} | |
} | |
println!("============================================================"); | |
for (k, v) in algos { | |
let millis = v.time.as_secs() as u32 * 1_000; | |
let nanos = v.time.subsec_nanos(); | |
let millis = millis + nanos / 1_000_000; | |
println!("{:<18} {:8} (-{:02.2}%) {:3}.{:03}ms", | |
k, | |
v.total_compressed, | |
100.0 - 100.0 * (v.total_compressed as f64 / (v.total_uncompressed as f64)), | |
millis, | |
(nanos % 1_000_000) / 1_000); | |
} | |
} | |
struct Algorithm { | |
total_uncompressed: usize, | |
total_compressed: usize, | |
time: Duration, | |
} | |
fn doit(name: &str, | |
algos: &mut BTreeMap<String, Algorithm>, | |
data: &[u8], | |
f: &mut FnMut(&[u8]) -> Vec<u8>) { | |
let start = Instant::now(); | |
let small = f(data); | |
let end = start.elapsed(); | |
let algo = algos.entry(name.to_string()).or_insert(Algorithm { | |
total_uncompressed: 0, | |
total_compressed: 0, | |
time: Duration::new(0, 0), | |
}); | |
algo.total_uncompressed += data.len(); | |
algo.total_compressed += small.len(); | |
algo.time += end; | |
let millis = end.as_secs() as u32 * 1_000; | |
let nanos = end.subsec_nanos(); | |
let millis = millis + nanos / 1_000_000; | |
println!("{:<18} {:8} (-{:02.2}%) {:3}.{:03}ms", | |
name, | |
small.len(), | |
100.0 - 100.0 * (small.len() as f64 / (data.len() as f64)), | |
millis, | |
(nanos % 1_000_000) / 1_000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment