Use ** instead of pow in Python

In Python, x**y is much faster than:

Julia is more than 5 times faster than Python at scalar exponentiation, while Go was in-between Python and Julia in performance.

Python

The test was run on Python 3.5, 3.6 and 3.7 with similar results. In all cases, the timing was the same for integer or float base or exponent.

Python testing done with:

  • Python 3.7.2
  • Ipython 7.4.0
  • Numpy 1.16.1

** operator

The ** operator in Python also has the advantage of returning int if inputs are int and arithmetic result is integer.

%timeit 10**(-3)

18.8 ns ± 0.263 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

pow()

%timeit pow(10, -3)

490 ns ± 5.62 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

math.pow()

%timeit math.pow(10, -3)

572 ns ± 10.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

numpy.power()

Numpy is known in general to be slower at scalar operations than Python-native operators and Python built-in math. But of course Numpy is generally a lot faster and easier for N-dimensional array operations.

%timeit numpy.power(10, -3)

3.85 µs ± 440 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Julia

Julia 1.1.0 was likewise benchmarked for reference on the same computer. First we installed Julia BenchmarkTools:

import Pkg
Pkg.add("BenchmarkTools")

The Julia wallclock time for exponentiation was the same for float and int as with Python.

using BenchmarkTools

function caret(x, y)
  z = x ^ y

  return z
end

o = @benchmark caret(10, -3.)
println(minimum(o).time, " nanoseconds")

3.1 nanoseconds

Go

Create a file my_test.go containing:

package main

import ("math"
        "testing")

func BenchmarkPower(b *testing.B) {
    for i := 0; i < b.N; i++ {
        math.Pow(10, -3)
    }
}

then run

go test -bench=Power

Will result in something like:

BenchmarkPower-4        20000000                61.9 ns/op

go benchmark reference