From dbc3d97513bf98df0e1978c627635905505b4797 Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Fri, 19 Aug 2016 23:42:04 -0400 Subject: [PATCH] Eliminate many clones --- CHANGELOG.md | 1 + src/headers.rs | 2 +- src/lib.rs | 49 ++++++++++++++++++++++++------------------------ src/main.rs | 2 +- src/png.rs | 10 +++++----- src/reduction.rs | 10 +++++----- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc2ae22..881b5b68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - [SEMVER_MAJOR] Bump minimum rustc version to 1.9.0, required by dependencies - [SEMVER_MINOR] Allow calling optimization presets via crate using `Options::from_preset` - [SEMVER_MAJOR] Return proper `PngError` type which implements `std::error::Error` from `Result`s + - Performance optimizations **Version 0.10.0** - [SEMVER_MINOR] Make clap and regex dependencies optional diff --git a/src/headers.rs b/src/headers.rs index 2b8e5f0e..d5e32eef 100644 --- a/src/headers.rs +++ b/src/headers.rs @@ -85,7 +85,7 @@ pub fn parse_next_header(byte_data: &[u8], Err(_) => return Err(PngError::new("Invalid data found; unable to read PNG file")), }; *byte_offset += 4; - header_bytes.extend(data.clone()); + header_bytes.extend_from_slice(&data); if !fix_errors && crc32::checksum_ieee(header_bytes.as_ref()) != crc { return Err(PngError::new(&format!("CRC Mismatch in {} header; May be recoverable by using --fix", header))); diff --git a/src/lib.rs b/src/lib.rs index d62082cc..ce5894f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,7 +15,7 @@ use std::collections::{HashMap, HashSet}; use std::fs::{File, copy}; use std::io::{BufWriter, Write, stderr, stdout}; use std::path::{Path, PathBuf}; -use std::sync::{Arc, Mutex}; +use std::sync::Mutex; pub mod colors; pub mod deflate { @@ -425,7 +425,7 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op png.ihdr_data.width, png.ihdr_data.height) .ok(); - if let Some(palette) = png.palette.clone() { + if let Some(ref palette) = png.palette { writeln!(&mut stderr(), " {} bits/pixel, {} colors in palette", png.ihdr_data.bit_depth, @@ -450,8 +450,8 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op } let mut filter = opts.filter.clone(); - let compression = opts.compression.clone(); - let memory = opts.memory.clone(); + let compression = &opts.compression; + let memory = &opts.memory; let mut strategies = opts.strategies.clone(); if opts.use_heuristics { @@ -480,21 +480,21 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op let thread_count = opts.threads; let pool = Pool::new(thread_count); // Go through selected permutations and determine the best - let best: Arc>> = Arc::new(Mutex::new(None)); + let best: Mutex> = Mutex::new(None); let combinations = filter.len() * compression.len() * memory.len() * strategies.len(); let mut results: Vec<(u8, u8, u8, u8)> = Vec::with_capacity(combinations); - let filters: Arc>>> = - Arc::new(Mutex::new(HashMap::with_capacity(filter.len()))); + let filters: Mutex>> = + Mutex::new(HashMap::with_capacity(filter.len())); if opts.verbosity.is_some() { writeln!(&mut stderr(), "Trying: {} combinations", combinations).ok(); } pool.scoped(|scope| { for f in &filter { - let png = png.clone(); - let filters = filters.clone(); - for zc in &compression { - for zm in &memory { + let png = &png; + let filters = &filters; + for zc in compression { + for zm in memory { for zs in &strategies { results.push((*f, *zc, *zm, *zs)); } @@ -516,7 +516,7 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op opts.interlace != Some(png.ihdr_data.interlaced); for trial in &results { let filtered = filters.get(&trial.0).unwrap(); - let best = best.clone(); + let best = &best; scope.execute(move || { let new_idat = deflate::deflate::deflate(filtered, trial.1, trial.2, trial.3, opts.window) @@ -546,7 +546,7 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op let mut final_best = best.lock().unwrap(); if let Some(better) = final_best.take() { - png.idat_data = better.4.clone(); + png.idat_data = better.4; if opts.verbosity.is_some() { writeln!(&mut stderr(), "Found better combination:").ok(); writeln!(&mut stderr(), @@ -650,7 +650,7 @@ fn perform_reductions(png: &mut png::PngData, opts: &Options) -> bool { /// Display the status of the image data after a reduction has taken place #[inline] fn report_reduction(png: &png::PngData) { - if let Some(palette) = png.palette.clone() { + if let Some(ref palette) = png.palette { writeln!(&mut stderr(), "Reducing image to {} bits/pixel, {} colors in palette", png.ihdr_data.bit_depth, @@ -668,26 +668,25 @@ fn report_reduction(png: &png::PngData) { /// Strip headers from the `PngData` object, as requested by the passed `Options` fn perform_strip(png: &mut png::PngData, opts: &Options) { - match opts.strip.clone() { + match &opts.strip { // Strip headers - Headers::None => (), - Headers::Some(hdrs) => { - for hdr in &hdrs { + &Headers::None => (), + &Headers::Some(ref hdrs) => { + for hdr in hdrs { png.aux_headers.remove(hdr); } } - Headers::Safe => { + &Headers::Safe => { const PRESERVED_HEADERS: [&'static str; 9] = ["cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "pHYs", "sPLT"]; - let mut preserved = HashMap::new(); - for (hdr, contents) in &png.aux_headers { - if PRESERVED_HEADERS.contains(&hdr.as_ref()) { - preserved.insert(hdr.clone(), contents.clone()); + let hdrs = png.aux_headers.keys().cloned().collect::>(); + for hdr in hdrs { + if !PRESERVED_HEADERS.contains(&hdr.as_ref()) { + png.aux_headers.remove(&hdr); } } - png.aux_headers = preserved; } - Headers::All => { + &Headers::All => { png.aux_headers = HashMap::new(); } } diff --git a/src/main.rs b/src/main.rs index 3df68581..44e4f7c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -236,7 +236,7 @@ fn handle_optimization(inputs: Vec, opts: Options) { } continue; } - if let Some(out_dir) = current_opts.out_dir.clone() { + if let Some(ref out_dir) = current_opts.out_dir { current_opts.out_file = out_dir.join(input.file_name().unwrap()); } else if current_opts.out_file.components().count() == 0 { current_opts.out_file = input.clone(); diff --git a/src/png.rs b/src/png.rs index e51a7f33..7bdc25f3 100644 --- a/src/png.rs +++ b/src/png.rs @@ -251,7 +251,7 @@ impl PngData { } } let mut png_data = PngData { - idat_data: idat_headers.clone(), + idat_data: idat_headers, ihdr_data: ihdr_header, raw_data: raw_data, palette: aux_headers.remove("PLTE"), @@ -304,13 +304,13 @@ impl PngData { write_png_block(key.as_bytes(), header, &mut output); } // Palette - if let Some(palette) = self.palette.clone() { + if let Some(ref palette) = self.palette { write_png_block(b"PLTE", &palette, &mut output); - if let Some(transparency_palette) = self.transparency_palette.clone() { + if let Some(ref transparency_palette) = self.transparency_palette { // Transparency pixel write_png_block(b"tRNS", &transparency_palette, &mut output); } - } else if let Some(transparency_pixel) = self.transparency_pixel.clone() { + } else if let Some(ref transparency_pixel) = self.transparency_pixel { // Transparency pixel write_png_block(b"tRNS", &transparency_pixel, &mut output); } @@ -405,7 +405,7 @@ impl PngData { } _ => unreachable!(), } - last_line = line.data.clone(); + last_line = line.data; last_pass = line.pass; } filtered diff --git a/src/reduction.rs b/src/reduction.rs index cd8e126b..40b2ad2d 100644 --- a/src/reduction.rs +++ b/src/reduction.rs @@ -123,10 +123,10 @@ pub fn reduce_rgba_to_palette(png: &PngData) -> Option<(Vec, Vec, Vec Option<(Vec, Vec)> { if len == 256 { return None; } - palette.push(cur_pixel.clone()); + palette.push(cur_pixel); reduced.push(len as u8); } - cur_pixel.clear(); + cur_pixel = Vec::with_capacity(bpp); } } } @@ -211,7 +211,7 @@ pub fn reduce_grayscale_to_palette(png: &PngData) -> Option<(Vec, Vec)> if len == 16 { return None; } - palette.push(pix_slice.clone()); + palette.push(pix_slice); let idx = BitVec::from_bytes(&[(len as u8) << bpp_inverse]); for b in idx.iter().take(bpp) { reduced.push(b);