# Slow exp()?

**URL:** https://discourse.julialang.org/t/slow-exp/13606
**Category:** Numerics
**Tags:** fast-math
**Created:** [August 17, 2018, 6:39am UTC](https://discourse.julialang.org/t/slow-exp/13606 "2018-08-17T06:39:51Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 17, 2018, 6:39am UTC](https://discourse.julialang.org/t/slow-exp/13606/1 "2018-08-17T06:39:51Z")

</div>

```julia
julia> exp(1.3)
3.6692966676192444

julia> exp(1)
2.718281828459045

julia> 2.718281828459045 ^ 1.3
3.669296667619244

julia> @benchmark exp(1.3)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 11.863 ns (0.00% GC)
  median time: 13.235 ns (0.00% GC)
  mean time: 13.247 ns (0.00% GC)
  maximum time: 72.282 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 999

julia> @benchmark 2.718281828459045 ^ 1.3
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 1.564 ns (0.00% GC)
  median time: 1.649 ns (0.00% GC)
  mean time: 1.721 ns (0.00% GC)
  maximum time: 12.501 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

Apart from a little inaccuracy, seems like “2.718281828459045 ^” is much faster than “exp()”. Similarly, “2.0 ^” is faster than “exp2()”, but exp() is particularly slow:

```julia
julia> @benchmark exp2(1.3)
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 5.700 ns (0.00% GC)
  median time: 5.730 ns (0.00% GC)
  mean time: 5.959 ns (0.00% GC)
  maximum time: 29.321 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

julia> @benchmark 2.0 ^ 1.3
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 1.564 ns (0.00% GC)
  median time: 1.572 ns (0.00% GC)
  mean time: 1.636 ns (0.00% GC)
  maximum time: 12.150 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

any suggestions?

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [August 17, 2018, 6:59am UTC](https://discourse.julialang.org/t/slow-exp/13606/2 "2018-08-17T06:59:25Z")

</div>

Put it in functions:

```julia
julia> f() = exp(1.3);

julia> g() = 2.718281828459045 ^ 1.3;

julia> @btime f();
  1.815 ns (0 allocations: 0 bytes)

julia> @btime g();
  1.815 ns (0 allocations: 0 bytes)

```

Also, llvm is smart, so we are not actually doing a computation at all, just returning the answer:

```julia
julia> @code_llvm f()

; Function f
; Location: REPL[1]:1
define double @julia_f_35198() {
top:
  ret double 0x400D5AB83615F8B4
}

```

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [August 17, 2018, 7:44am UTC](https://discourse.julialang.org/t/slow-exp/13606/3 "2018-08-17T07:44:27Z")

</div>

> [@tomtom](#):
>
> any suggestions?

```julia

julia> f(x) = exp(x)
f (generic function with 1 method)

julia> g(x) = 2.718281828459045^x
g (generic function with 1 method)

julia> using BenchmarkTools

julia> @btime f($1.3)
  11.023 ns (0 allocations: 0 bytes)
3.6692966676192444

julia> @btime g($1.3)
  91.612 ns (0 allocations: 0 bytes)
3.669296667619244

```

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [August 17, 2018, 8:46am UTC](https://discourse.julialang.org/t/slow-exp/13606/5 "2018-08-17T08:46:27Z")

</div>

Actually, I can replicate this both on Julia 0.6 and 0.7. The code looks like this:

```julia
julia> @code_llvm f(1.3)

define double @julia_f_63011(double) #0 !dbg !5 {
top:
  %1 = call double @julia_exp_62847(double %0)
  ret double %1
}

julia> @code_llvm g(1.3)

define double @julia_g_62927(double) #0 !dbg !5 {
top:
  %1 = call double @llvm.pow.f64(double 0x4005BF0A8B145769, double %0)
  %2 = fadd double %0, 0x4005BF0A8B145769
  %notlhs = fcmp ord double %1, 0.000000e+00
  %notrhs = fcmp uno double %2, 0.000000e+00
  %3 = or i1 %notrhs, %notlhs
  br i1 %3, label %L9, label %if

if: ; preds = %top
  call void @jl_throw(i8**inttoptr (i64 140113430158408 to i8**))
  unreachable

L9: ; preds = %top
  ret double %1
}

```

In other words, exp() is fast. 🙂

---

<div class="post-metadata">

### Author: ![fruno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fruno/32/5013_2.png) [@fruno](https://discourse.julialang.org/u/fruno)
#### Post date: [August 17, 2018, 9:16am UTC](https://discourse.julialang.org/t/slow-exp/13606/6 "2018-08-17T09:16:32Z")

</div>

Sort of “related” to this (and it’s Friday, so cut me some slack. 🙂).

Computing `log10(x)` using `log(x)*log10(exp(1))`, with `log10(exp(1))` replaced by the resulting “numerical value”, is faster than `log10(x)` according to the benchmark tools (if I’m using them properly?). Obviously not producing _exactly_ the same value, but sometimes speed trumps accuracy… Julia 1.0.0/Windows 7.

```julia
using BenchmarkTools

f1(x) = log(x)*0.4342944819032518

@btime log10($1.3)
  22.895 ns (0 allocations: 0 bytes)
0.11394335230683679

@btime f1($1.3)
  8.684 ns (0 allocations: 0 bytes)
0.11394335230683678

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 17, 2018, 9:17am UTC](https://discourse.julialang.org/t/slow-exp/13606/7 "2018-08-17T09:17:03Z")

</div>

Hm, how can you see that `exp` is fast from this? In the LLVM code there it just calls another function.

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 17, 2018, 9:24am UTC](https://discourse.julialang.org/t/slow-exp/13606/8 "2018-08-17T09:24:25Z")

</div>

amazing. thanks. I’ve learned a lot.

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [August 17, 2018, 10:00am UTC](https://discourse.julialang.org/t/slow-exp/13606/9 "2018-08-17T10:00:30Z")

</div>

> [@fruno](#):
>
> but sometimes speed trumps accuracy

Yes, this is something that is useful to keep in mind. Generally, if a function is called something like `log10` (or `exp` or …) it will be implemented as fast as possible, but within the constraints of being within 1ulp of the “true solution”. That is, not quite correctly rounded, but quite close still. I’m not sure what the worst case error is for your `f1`, but I’m certain that it is not 1ulp.

That said, we do have a `@fastmath` macro, and there’s certainly more we could do with that, to actually make it choose faster less accurate versions for all the elementary functions.

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 17, 2018, 10:20am UTC](https://discourse.julialang.org/t/slow-exp/13606/10 "2018-08-17T10:20:50Z")

</div>

sorry, I’m confused.

what’s `@fastmath`? (I cannot find docs about it). Also, I see `Base.FastMath`, what is it???

I mean, if there _exists_ faster maths, why keep the original (slower) maths ???

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 17, 2018, 10:22am UTC](https://discourse.julialang.org/t/slow-exp/13606/11 "2018-08-17T10:22:03Z")

</div>

> [@tomtom](#):
>
> I mean, if there _exists_ faster maths, why keep the original (slower) maths ???

faster math means in some cases less accurate math.

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [August 17, 2018, 10:32am UTC](https://discourse.julialang.org/t/slow-exp/13606/12 "2018-08-17T10:32:06Z")

</div>

That’s interesting. It was quite easy for me to find the documentation. How’d you look?

in the docs search functionality  
[https://docs.julialang.org/en/v1.0.0/search/?q=fastmath](https://docs.julialang.org/en/v1.0.0/search/?q=fastmath)

and in the repl

 ![weird](https://global.discourse-cdn.com/julialang/original/3X/8/9/89690da695a2d14e8abec2618af868cbd9696e58.png)

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 17, 2018, 11:03am UTC](https://discourse.julialang.org/t/slow-exp/13606/13 "2018-08-17T11:03:24Z")

</div>

I’m using JuliaPro 0.6.3 … and somehow there is no help on @fastmath ???

```julia
help?> @fastmath
No documentation found.
Base.FastMath.@fastmath is a macro.
# 1 method for macro "@fastmath":
@fastmath(expr::ANY) in Base.FastMath at fastmath.jl:127

```

so, starting julia --math-mode=fast would put _all_ maths in fastmath mode?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 17, 2018, 11:10am UTC](https://discourse.julialang.org/t/slow-exp/13606/14 "2018-08-17T11:10:44Z")

</div>

> [@tomtom](#):
>
> I’m using JuliaPro 0.6.3 … and somehow there is no help on @fastmath ???

I think the docs were added in 0.7.
