# Small, fixed powers

**URL:** <https://discourse.julialang.org/t/small-fixed-powers/61991>\
**Category:** Performance\
**Created:** [May 28, 2021, 1:32pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991 "2021-05-28T13:32:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![scheinerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scheinerman/32/35303_2.png) [@scheinerman](https://discourse.julialang.org/u/scheinerman)\
**Post date:** [May 28, 2021, 1:32pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/1 "2021-05-28T13:32:10Z")

</div>

Consider these two functions for computing the 4-th power:

```julia
power4(x) = x^4
power31(x) = x * x^3

```

The second is much speedier than the first because (looking at `code_llvm` or `code_native`) the first calls a general helper function and the second just does two multiplies. Indeed, the second is intelligently compiled and essentially does this:

```julia
y = x*x
return y*y

```

Running Julia with `-O3` optimization doesn’t help.

It appears that fixed exponents from `-1` to `3` are handled well. Consider this:

```julia
julia> code_llvm(x -> x^3 * x^3 * x^3, (Int,))
; @ REPL[9]:1 within `#15'
define i64 @"julia_#15_176"(i64 signext %0) {
top:
; ┌ @ operators.jl:560 within `*' @ int.jl:88
   %1 = mul i64 %0, %0
   %2 = mul i64 %1, %1
   %3 = mul i64 %2, %0
   %4 = mul i64 %3, %2
; └
  ret i64 %4
}

```

That’s terrific: Computing `x^9` is reduced to four multiplies.

It may be worthwhile for exponentiation by small, fixed exponents (larger than 3) be compiled directly into multiplications (including for other types such as matrices and polynomials).

---

<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:** [May 28, 2021, 1:42pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/2 "2021-05-28T13:42:04Z")

</div>

> [@scheinerman](#):
>
> It may be worthwhile for exponentiation by small, fixed exponents (larger than 3) be compiled directly into multiplications (including for other types such as matrices and polynomials).

This is totally possible to do — see e.g. [inline ^ for literal powers of numbers by stevengj · Pull Request #20637 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/20637) — but it is slightly less accurate so the argument was that it should only be done in `@fastmath` mode or similar.

It would be easy to put this into a package, with a `@fastpow` macro that turns literal powers in a block of code into optimal addition-chain multiplications (by adapting the PR above), for example.

---

<div class="post-metadata">

**Author:** ![scheinerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scheinerman/32/35303_2.png) [@scheinerman](https://discourse.julialang.org/u/scheinerman)\
**Post date:** [May 28, 2021, 1:57pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/3 "2021-05-28T13:57:45Z")

</div>

I didn’t know about the `@fastmath` macro. Thanks.

---

<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:** [May 28, 2021, 2:33pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/4 "2021-05-28T14:33:17Z")

</div>

To be clear, the `@fastmath` macro doesn’t necessarily do optimal addition-chain exponentiation as far as I know? It switches from the `llvm.pow` intrinsic to `llvm.powi` (at least for hardware floating-point types, not for complex numbers etcetera), so it depends on what `powi` does.

For fun, I just posted a package with a `@fastpow` macro that implements optimal (fewest-multiply) exponents for literal integer powers:

> **[GitHub - JuliaMath/FastPow.jl: optimal addition-chain exponentiation for Julia](https://github.com/JuliaMath/FastPow.jl)**
>
> optimal addition-chain exponentiation for Julia. Contribute to JuliaMath/FastPow.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [May 28, 2021, 2:40pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/5 "2021-05-28T14:40:32Z")

</div>

FastPow link is not working

---

<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:** [May 28, 2021, 2:41pm UTC](https://discourse.julialang.org/t/small-fixed-powers/61991/6 "2021-05-28T14:41:32Z")

</div>

Should be fixed now, sorry.
