1 #![feature(test)]
2 extern crate rustfft;
3 extern crate test;
4 
5 use paste::paste;
6 use rustfft::num_complex::Complex;
7 use rustfft::num_traits::Zero;
8 use rustfft::Fft;
9 use std::sync::Arc;
10 use test::Bencher;
11 
12 // Make fft using scalar planner
bench_scalar_32(b: &mut Bencher, len: usize)13 fn bench_scalar_32(b: &mut Bencher, len: usize) {
14     let mut planner = rustfft::FftPlannerScalar::new();
15     let fft: Arc<dyn Fft<f32>> = planner.plan_fft_forward(len);
16 
17     let mut buffer: Vec<Complex<f32>> = vec![Complex::zero(); len];
18     let mut scratch: Vec<Complex<f32>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
19     b.iter(|| {
20         fft.process_with_scratch(&mut buffer, &mut scratch);
21     });
22 }
23 
24 // Make fft using scalar planner
bench_scalar_64(b: &mut Bencher, len: usize)25 fn bench_scalar_64(b: &mut Bencher, len: usize) {
26     let mut planner = rustfft::FftPlannerScalar::new();
27     let fft: Arc<dyn Fft<f64>> = planner.plan_fft_forward(len);
28 
29     let mut buffer: Vec<Complex<f64>> = vec![Complex::zero(); len];
30     let mut scratch: Vec<Complex<f64>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
31     b.iter(|| {
32         fft.process_with_scratch(&mut buffer, &mut scratch);
33     });
34 }
35 
36 // Make fft using sse planner
bench_sse_32(b: &mut Bencher, len: usize)37 fn bench_sse_32(b: &mut Bencher, len: usize) {
38     let mut planner = rustfft::FftPlannerSse::new().unwrap();
39     let fft: Arc<dyn Fft<f32>> = planner.plan_fft_forward(len);
40 
41     let mut buffer: Vec<Complex<f32>> = vec![Complex::zero(); len];
42     let mut scratch: Vec<Complex<f32>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
43     b.iter(|| {
44         fft.process_with_scratch(&mut buffer, &mut scratch);
45     });
46 }
47 
48 // Make fft using sse planner
bench_sse_64(b: &mut Bencher, len: usize)49 fn bench_sse_64(b: &mut Bencher, len: usize) {
50     let mut planner = rustfft::FftPlannerSse::new().unwrap();
51     let fft: Arc<dyn Fft<f64>> = planner.plan_fft_forward(len);
52 
53     let mut buffer: Vec<Complex<f64>> = vec![Complex::zero(); len];
54     let mut scratch: Vec<Complex<f64>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
55     b.iter(|| {
56         fft.process_with_scratch(&mut buffer, &mut scratch);
57     });
58 }
59 
60 // Make fft using sse planner
bench_avx_32(b: &mut Bencher, len: usize)61 fn bench_avx_32(b: &mut Bencher, len: usize) {
62     let mut planner = rustfft::FftPlannerAvx::new().unwrap();
63     let fft: Arc<dyn Fft<f32>> = planner.plan_fft_forward(len);
64 
65     let mut buffer: Vec<Complex<f32>> = vec![Complex::zero(); len];
66     let mut scratch: Vec<Complex<f32>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
67     b.iter(|| {
68         fft.process_with_scratch(&mut buffer, &mut scratch);
69     });
70 }
71 
72 // Make fft using sse planner
bench_avx_64(b: &mut Bencher, len: usize)73 fn bench_avx_64(b: &mut Bencher, len: usize) {
74     let mut planner = rustfft::FftPlannerAvx::new().unwrap();
75     let fft: Arc<dyn Fft<f64>> = planner.plan_fft_forward(len);
76 
77     let mut buffer: Vec<Complex<f64>> = vec![Complex::zero(); len];
78     let mut scratch: Vec<Complex<f64>> = vec![Complex::zero(); fft.get_inplace_scratch_len()];
79     b.iter(|| {
80         fft.process_with_scratch(&mut buffer, &mut scratch);
81     });
82 }
83 
84 // Create benches using functions taking one argument
85 macro_rules! make_benches {
86     ($name:ident, { $($len:literal),* }) => {
87         paste! {
88             $(
89                 #[bench]
90                 fn [<$name _ $len _f32_scalar>](b: &mut Bencher)  {
91                     [<bench_scalar_32>](b, $len);
92                 }
93 
94                 #[bench]
95                 fn [<$name _ $len _f64_scalar>](b: &mut Bencher)  {
96                     [<bench_scalar_64>](b, $len);
97                 }
98 
99                 #[bench]
100                 fn [<$name _ $len _f32_sse>](b: &mut Bencher)  {
101                     [<bench_sse_32>](b, $len);
102                 }
103 
104                 #[bench]
105                 fn [<$name _ $len _f64_sse>](b: &mut Bencher)  {
106                     [<bench_sse_64>](b, $len);
107                 }
108 
109                 #[bench]
110                 fn [<$name _ $len _f32_avx>](b: &mut Bencher)  {
111                     [<bench_avx_32>](b, $len);
112                 }
113 
114                 #[bench]
115                 fn [<$name _ $len _f64_avx>](b: &mut Bencher)  {
116                     [<bench_avx_64>](b, $len);
117                 }
118             )*
119         }
120     }
121 }
122 
123 make_benches!(comparison, {16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 });
124 make_benches!(comparison, {65536, 131072, 262144, 524288, 1048576, 2097152, 4194304 });
125