# @btime of cis Function slower than writing it again

**URL:** <https://discourse.julialang.org/t/btime-of-cis-function-slower-than-writing-it-again/86318>\
**Category:** Numerics\
**Tags:** performance, benchmarktools\
**Created:** [August 25, 2022, 12:07pm UTC](https://discourse.julialang.org/t/btime-of-cis-function-slower-than-writing-it-again/86318 "2022-08-25T12:07:06Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)\
**Post date:** [August 25, 2022, 12:07pm UTC](https://discourse.julialang.org/t/btime-of-cis-function-slower-than-writing-it-again/86318/1 "2022-08-25T12:07:06Z")

</div>

I found a quite strange effect when evaluating the performance of `cis ` via @btime:

```julia
sz = (2000,2000)
a = Float32.(2pi .* rand(sz...));
function cis_fast(phi::T) where {T<:Real}
    complex(sincos(T(pi/2) .- phi)...)
end
r = zeros(ComplexF32, sz);
@btime $r .= cis_fast.($a); # 42 ms 
@btime $r .= cis.($a); # 46 ms

```

For the function as written, I consistently get faster results as the inbuilt version. I find this odd, since the inbuilt version looks like it requires fewer calculations. Tested in Julia 1.7.1 and 1.8.0.

---

<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:** [August 25, 2022, 1:04pm UTC](https://discourse.julialang.org/t/btime-of-cis-function-slower-than-writing-it-again/86318/2 "2022-08-25T13:04:15Z")

</div>

It looks like it has to do with [argument reduction](https://docs.oracle.com/cd/E37069_01/html/E39019/z4000ac119729.html).

The `sincos` function, along with other trig functions, [is fastest for](https://github.com/JuliaLang/julia/blob/36aab14a97a6ae6fb937577601e44134c24a0e37/base/special/trig.jl#L179) arguments in [-\pi/4, \pi/4], and otherwise has to [reduce the argument modulo π/2](https://github.com/JuliaLang/julia/blob/36aab14a97a6ae6fb937577601e44134c24a0e37/base/special/trig.jl#L185) to that range. For your arguments distributed uniformly in [0,2\pi), computing \pi/2 - \phi increases the probability of the argument being in [-\pi/4, \pi/4], and hence speeds it up on average.

If you do `a = Float32.((pi/2) .* rand(sz...))`, then \pi/2 - \phi does not change the distribution of magnitudes and hence the two functions become about equally fast on my machine.

---

<div class="post-metadata">

**Author:** ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)\
**Post date:** [August 25, 2022, 1:13pm UTC](https://discourse.julialang.org/t/btime-of-cis-function-slower-than-writing-it-again/86318/3 "2022-08-25T13:13:35Z")

</div>

> [@stevengj](#):
>
> a = Float32.((pi/2) .\* rand(sz…))

Fantastic. I did not think of this, but it explains it. Good to know that that range is optimal.
