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
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.
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.
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.
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.