From 9721004ad0d82d2ed5507305e3526e32652f524d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 17 Dec 2014 08:53:09 +0100 Subject: [PATCH] Use Cow for formats conversions to avoid an allocation and copy --- src/lib.rs | 16 +++++++++++++-- src/samples_formats.rs | 45 +++++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2c75fa4..1786d8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,9 +184,21 @@ impl<'a, T> Drop for Buffer<'a, T> where T: Sample { macro_rules! write_to_buf( ($buf:expr, $output:expr, $ty:ty) => ({ + use std::borrow::Cow; + let output: &mut [$ty] = unsafe { std::mem::transmute($output) }; - for (i, o) in $buf.into_iter().zip(output.iter_mut()) { - *o = i; + + match $buf { + Cow::Borrowed(buf) => { + for (i, o) in buf.iter().zip(output.iter_mut()) { + *o = *i; + } + }, + Cow::Owned(buf) => { + for (i, o) in buf.into_iter().zip(output.iter_mut()) { + *o = i; + } + } } }) ) diff --git a/src/samples_formats.rs b/src/samples_formats.rs index c192ad0..e11db03 100644 --- a/src/samples_formats.rs +++ b/src/samples_formats.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::mem; /// Format that each sample has. @@ -26,11 +27,11 @@ pub trait Sample: Copy { fn get_format(Option) -> SampleFormat; /// Turns the data into a `Vec` where each element is a sample. - fn to_vec_i16(&[Self]) -> Vec; + fn to_vec_i16(&[Self]) -> Cow, [i16]>; /// Turns the data into a `Vec` where each element is a sample. - fn to_vec_u16(&[Self]) -> Vec; + fn to_vec_u16(&[Self]) -> Cow, [u16]>; /// Turns the data into a `Vec` where each element is a sample. - fn to_vec_f32(&[Self]) -> Vec; + fn to_vec_f32(&[Self]) -> Cow, [f32]>; } impl Sample for u16 { @@ -38,22 +39,22 @@ impl Sample for u16 { SampleFormat::U16 } - fn to_vec_i16(input: &[u16]) -> Vec { - input.iter().map(|&value| { + fn to_vec_i16(input: &[u16]) -> Cow, [i16]> { + Cow::Owned(input.iter().map(|&value| { if value >= 32768 { (value - 32768) as i16 } else { (value as i16) - 32767 } - }).collect() + }).collect()) } - fn to_vec_u16(input: &[u16]) -> Vec { - input.to_vec() + fn to_vec_u16(input: &[u16]) -> Cow, [u16]> { + Cow::Borrowed(input) } - fn to_vec_f32(input: &[u16]) -> Vec { - Sample::to_vec_f32(Sample::to_vec_i16(input).as_slice()) + fn to_vec_f32(input: &[u16]) -> Cow, [f32]> { + Cow::Owned(Sample::to_vec_f32(Sample::to_vec_i16(input).as_slice()).to_vec()) } } @@ -62,24 +63,24 @@ impl Sample for i16 { SampleFormat::I16 } - fn to_vec_i16(input: &[i16]) -> Vec { - input.to_vec() + fn to_vec_i16(input: &[i16]) -> Cow, [i16]> { + Cow::Borrowed(input) } - fn to_vec_u16(input: &[i16]) -> Vec { - input.iter().map(|&value| { + fn to_vec_u16(input: &[i16]) -> Cow, [u16]> { + Cow::Owned(input.iter().map(|&value| { if value < 0 { (value + 32767) as u16 } else { (value as u16) + 32768 } - }).collect() + }).collect()) } - fn to_vec_f32(input: &[i16]) -> Vec { - input.iter().map(|&value| { + fn to_vec_f32(input: &[i16]) -> Cow, [f32]> { + Cow::Owned(input.iter().map(|&value| { value as f32 / 32768.0 - }).collect() + }).collect()) } } @@ -88,15 +89,15 @@ impl Sample for f32 { SampleFormat::F32 } - fn to_vec_i16(input: &[f32]) -> Vec { + fn to_vec_i16(input: &[f32]) -> Cow, [i16]> { unimplemented!() } - fn to_vec_u16(input: &[f32]) -> Vec { + fn to_vec_u16(input: &[f32]) -> Cow, [u16]> { unimplemented!() } - fn to_vec_f32(input: &[f32]) -> Vec { - input.to_vec() + fn to_vec_f32(input: &[f32]) -> Cow, [f32]> { + Cow::Borrowed(input) } }