diff --git a/Cargo.toml b/Cargo.toml index 8802503..ac67be2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,12 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bench]] +name = "benchmark" +harness = false + [dependencies] bit-vec = "0.6.3" + +[dev-dependencies] +criterion = { version = "0.4.0", features = ["html_reports"] } diff --git a/assets/bench_input.txt b/assets/bench_input.txt new file mode 100644 index 0000000..7fda608 --- /dev/null +++ b/assets/bench_input.txt @@ -0,0 +1,9 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut leo tellus. Nam vehicula rutrum purus sed posuere. Donec imperdiet id ex in pulvinar. Vestibulum tristique erat eros, eu scelerisque sem sagittis eu. Aenean quis porttitor lectus. Suspendisse lobortis vestibulum lorem id tincidunt. Donec volutpat, turpis id fringilla tempus, lectus mauris dignissim nulla, finibus maximus enim augue ut risus. + +Donec viverra purus tellus, in sagittis orci dictum eget. Donec in facilisis diam, non tempor sem. Nunc imperdiet mattis mi in rutrum. Vivamus non vestibulum libero, a rutrum tortor. Maecenas efficitur neque lectus, in porttitor magna finibus quis. Nunc auctor posuere risus sit amet commodo. Curabitur mattis augue ante, sed molestie sapien vestibulum quis. Praesent non metus et leo fringilla posuere ut at metus. Cras finibus urna at massa cursus, at gravida diam luctus. Sed dolor odio, posuere non pretium at, elementum sed sem. In sollicitudin lectus at mi convallis aliquet. Mauris vitae egestas nunc. Phasellus et lacus condimentum, commodo arcu et, cursus ipsum. + +Fusce vulputate tincidunt justo eget semper. Aliquam elementum metus ligula, et vestibulum quam rhoncus ac. Integer vehicula eget lorem sit amet rhoncus. Vestibulum dictum euismod nisl, a tincidunt nulla maximus et. Vivamus sed nibh eget magna tristique posuere. Ut malesuada nisi vel est dictum, cursus tempor nisl venenatis. Vestibulum eu dui non magna porta pellentesque et quis nibh. Nulla facilisi. + +Suspendisse vulputate felis nec mattis ultricies. Phasellus non accumsan purus, vel consectetur ex. Nullam eu urna eu tortor elementum efficitur. Mauris nec mollis sapien. Morbi id est in arcu porta tristique eget sed diam. Aliquam mattis accumsan aliquam. In ac arcu dictum ante euismod pretium. Maecenas congue aliquam tellus, ac tempor massa fermentum a. Proin ultricies ex et ligula lacinia, eu lacinia libero placerat. Nunc ullamcorper eu velit vel rhoncus. Nunc ut purus non tortor pulvinar faucibus. Fusce convallis sit amet sapien laoreet porta. + +Phasellus rutrum cursus blandit. In sed pharetra diam. Curabitur lobortis, diam eu imperdiet ornare, enim lacus maximus tellus, et maximus quam libero eu nisl. Ut at dui ante. Morbi quis leo mattis, tincidunt velit sit amet, faucibus est. Mauris interdum nisi ut aliquam laoreet. Vivamus at elit quam. Pellentesque vestibulum placerat blandit. \ No newline at end of file diff --git a/benches/benchmark.rs b/benches/benchmark.rs new file mode 100644 index 0000000..aae0150 --- /dev/null +++ b/benches/benchmark.rs @@ -0,0 +1,22 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use rustyman::Huffman; + + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("compress", |b| { + let huffman = Huffman::new_from_data(include_bytes!("../assets/bench_input.txt")); + let data = include_bytes!("../assets/bench_input.txt"); + b.iter_with_large_drop(|| huffman.compress(black_box(data))); + }); + + c.bench_function("decompress", |b| { + let huffman = Huffman::new_from_data(include_bytes!("../assets/bench_input.txt")); + let data = include_bytes!("../assets/bench_input.txt"); + let compressed = huffman.compress(data); + + b.iter_with_large_drop(|| huffman.decompress(black_box(&compressed))); + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 936dbb1..fc0c17a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ use bit_vec::BitVec; // - https://aquarchitect.github.io/swift-algorithm-club/Huffman%20Coding/ #[derive(Debug, Clone, Copy)] -pub struct Node { +struct Node { pub data: Option, pub count: usize, pub index: Option, @@ -61,6 +61,7 @@ pub struct Huffman { } impl Huffman { + /// Initializes the huffman interface using the provided frequency table. pub fn new(frequency_table: &HashMap) -> Self { let tree = Self::build_tree(frequency_table); let indexes = tree @@ -72,11 +73,12 @@ impl Huffman { Self { tree, indexes } } - /// Creates the Huffman frequency table from the provided data. + /// Creates the Huffman frequency table from the provided data and initializes from it. pub fn new_from_data(data: &[u8]) -> Self { Self::new(&Self::calculate_freq_table(data)) } + /// Calculates the frequency table from the provided data. pub fn calculate_freq_table(data: &[u8]) -> HashMap { let mut table: HashMap = HashMap::with_capacity(256.min(data.len() / 2)); @@ -155,6 +157,7 @@ impl Huffman { } } + /// Compresses the provided data. pub fn compress(&self, data: &[u8]) -> Vec { let mut bits = BitVec::new(); @@ -172,6 +175,7 @@ impl Huffman { bits.to_bytes() } + /// Decompresses the provided data. pub fn decompress(&self, data: &[u8]) -> Vec { let bits = BitVec::from_bytes(data); let mut decompressed = Vec::with_capacity(bits.len() * 2);