I need help to make my small calculation faster

Hi,

I need to do this calculation every 1/48000 second for my audio program. So it must be fast. I will not show my first attempt here, but it was not good. So I came up with this instead:

for i in 0..NR_OF_SINES {
    let product_value = freqs[i] * sample_clock as f32 * pi_twice;
    let sin_value = product_value.sin();
    res += amps[i] * sin_value;
}

NR_OF_SINES is about 2000. It is basically calculating 2000 sine waves and taking a sum of them:

General formula: A*sin(2*pi*f*t)
With my variable names: amps[i]*sin(2*pi*freqs[i]*sample_clock)

I have tried using iterators instead, but that was much slower. I also tried using iterators with rayon (with .par_iter()), that was even slower.

I was just wondering if you have any suggestions to make this faster.

There was a "_result" in my code, so the calculation time was 0. I have corrected that. And updated the link. Here is a link to the code on playground: Rust Playground

You might be measuring wrong. The playground you linked prints (when compiled with optimizations on)

my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc: 0
my_calc average time was: 0.0

I mean, maybe more clearly: you are measuring wrong, and this might or might not be the only reason why you get things like iterator-based versions being slower.

Try some proper benchmarking tooling such as criterion and see if that gives you different results.

2 Likes

let _result = calc() actually seems to compile to nothing in release mode. If I change it to show the first item in _result I get around 12ms per iteration in release and 80 in debug.

1 Like

Thank for noticing. I have changed the "_result" to "results" and updated the link.

Looking at the code in your playground example I see it does a lot of matching on the array index i , checking what range it is in. That is a lot of conditional code in your loop.

Perhaps it would help to split that loop into 4 separate loops executed one after the other that operate over their respective array ranges. That would remove all the conditionals from the loop bodies.

Does the freqs array change between calls? If not, you can precalculate the sines. nvm, the time changes.

This looks suspiciously like a sine transform of the amps array. I wonder if an FFT crate might be of use?

Interesting. I make a FFT to analyze and find the right frequencies, but I have not thought about using it to get back to time domain (ifft). Mainly because I throw away a lot of information (like phase and most parts of the frequencies). I will dig into your idea.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.