[Question/Implementation] Avoid copying memory on an operation over a vector and returning a slice:

Hi rustaceans!

So, I'll try to give you guys some context and an example code.

So, I have a function which is supposed to filter an array (filter as in signal processing instead of rust filter), and the function is supposed to "return" (or change a mutable parameter, there are different approaches) a filtered version of the input.

This so called "filtered" is naturally smaller the the original "input", since, for filtering, a few elements of the array is used for computing a single element of the "filtered" output. Thus, the return can be either smaller than the original signal, or the same size, (when I use a padded/extended version of the input signal)

The following is an extract of my current implementation.

fn filter(input: Vec<f64>) -> Vec<f64> {
    let input_length = input.len();

    let mut input_with_padding = vec![0.0; FILTER_ORDER];
    input_with_padding.extend(input); // Observation [1]

    let mut output_filtered = vec![0.0; input_length + FILTER_ORDER];

    for idx in 0..input_length {
        // bunch of math using "input[idx..(idx + filter_order)]" yielding "result"
        output_filtered[idx + FILTER_ORDER] = result;
    }
    output_filtered[filter_order..].to_vec() // Observation [2]
}

Thus, my concerns in a first look are looming in Observation [1/2] where it relies on copying memory and realoc of memory, probably..

How can I, in a sense, optimize, this code?

Would something like this work?

fn filter(mut input: Vec<f64>) -> Vec<f64> {
    let input_length = input.len();
    input.extend((0..FILTER_ORDER).map(|_| 0.0));
    // edit: I just realized that the zeros are supposed to be out front
    // this rotate will move them into place
    input.rotate_right(FILTER_ORDER);

    let mut data = input;
    
    for idx in 0..input_length {
        let (input, rest) = data.split_at_mut(idx + FILTER_ORDER);
        let input = &input[idx..];
        // use input to compute result
        let result = 0.0;
        
        rest[0] = result;
    }
    
    data.drain(..FILTER_ORDER);
    
    data
}

edit 2: This is semanically different from your code, because the input is not preserved. Which may or may not matter.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.