# R2r is surprisingly slower than complex fft

**URL:** <https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018>\
**Category:** Performance\
**Tags:** question, fftw\
**Created:** [November 10, 2022, 2:33am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018 "2022-11-10T02:33:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [November 10, 2022, 2:33am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/1 "2022-11-10T02:33:52Z")

</div>

```julia
const m=60

x=randn(m,m,m)
y=deepcopy(x)
p = FFTW.plan_r2r(y,FFTW.R2HC,flags=FFTW.MEASURE)
@btime mul!($y,$p,$x);

```

gives the result

```julia
572.302 μs (138 allocations: 10.16 KiB)

```

while

```julia
const m=60

x=randn(ComplexF64,m,m,m)
y=deepcopy(x)
p = plan_fft(y,flags=FFTW.MEASURE)
@btime mul!($y,$p,$x);

```

gives

```julia
551.774 μs (138 allocations: 10.16 KiB)

```

Have I missed some crucial point?

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [November 10, 2022, 2:59am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/2 "2022-11-10T02:59:50Z")

</div>

```julia
Julia Version 1.6.7
Commit 3b76b25b64 (2022-07-19 15:11 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, haswell)
Environment:
  JULIA_NUM_THREADS = 4

```

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [November 10, 2022, 3:28am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/3 "2022-11-10T03:28:10Z")

</div>

And any chance StructArrays can be used in FFTW?

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [November 13, 2022, 8:05am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/4 "2022-11-13T08:05:29Z")

</div>

Have you tried calling fft on the array directly, to see if you have the same relative performance?

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [November 13, 2022, 10:24am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/5 "2022-11-13T10:24:36Z")

</div>

```julia
const m=60

x=randn(m,m,m)
@btime FFTW.r2r!($x,FFTW.R2HC);

```

gives

```julia
2.510 ms (55 allocations: 4.16 KiB)

```

while

```julia
const m=60

x=randn(ComplexF64,m,m,m)
@btime fft!($x);

```

gives

```julia
2.868 ms (31 allocations: 2.72 KiB)

```

Is it normal?

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [November 13, 2022, 10:33am UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/6 "2022-11-13T10:33:33Z")

</div>

I honstestly have no idea. @stevengj could probably understand what goes on. (I hope it is okay pinging you like this)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 13, 2022, 2:58pm UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/7 "2022-11-13T14:58:34Z")

</div>

> [@photor](#):
>
> Have I missed some crucial point?

No. The complex (and r2c) FFT algorithms are much more optimized in FFTW than the r2r plans, e.g. the former use SIMD and the latter do not. So even though a complex FFT takes about twice as much arithmetic as an R2HC plan of the same size, the former’s greater optimization makes up for it.

As explained in [the FFTW manual](http://www.fftw.org/~fftw/fftw3_doc/The-Halfcomplex_002dformat-DFT.html), we generally recommend the r2c interface if what you want is a real-input DFT, especially in the multidimensional case. The r2hc algorithms are included mainly as stepping stones to other transforms, and because it is occasionally convenient to have a real-input DFT where the output is exactly the same size.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [November 15, 2022, 7:43pm UTC](https://discourse.julialang.org/t/r2r-is-surprisingly-slower-than-complex-fft/90018/8 "2022-11-15T19:43:01Z")

</div>

This is too bad since r2r is useful for Chebyshev transforms. I remember for certain degrees this caused ApproxFun to be much slower than Chebfun (which just translated it to an FFT).
