I was using complex numbers in gmpy2 and noticed that it was slow. I narrowed it down the exponentiation operator. At first I thought it was just because it was complex. But then I compared it to mpmath which uses gmpy2 and it was so much faster:
# tested using gmpy2 2.0.8, mpmath 1.1.0, python 3.8.5
>>> import timeit
>>> setup = '''
import gmpy2 as gm
import mpmath
a1 = gm.mpc(-12.5, 34.125)
a2 = gm.mpc(17, -45.875)
b1 = mpmath.mpc(-12.5, 34.125)
b2 = mpmath.mpc(17, -45.875)
'''
# using gmpy2
>>> timeit.timeit('a1 ** a2', setup)
87.13848301399992
>>> timeit.timeit('a1 ** 2', setup)
40.478690218
>>> timeit.timeit('pow(a1, 2)', setup)
40.70392542999991
# using mpmath
>>> timeit.timeit('b1 ** b2', setup)
51.799312732999965
>>> timeit.timeit('b1 ** 2', setup)
4.239320562999978
>>> timeit.timeit('pow(b1, 2)', setup)
4.293315565000057
# multiplication comparison
>>> timeit.timeit('a1 * a1', setup)
0.9900801109999975 # gmpy2
>>> timeit.timeit('b1 * b1', setup)
4.711916033999955 # mpmath
Pure complex exponentiation is incredibly slow, but mpmath is still some 40% faster than gmpy2. Since mpmath is Python I figured it would be much slower but that's clearly not the case. How is gmpy2 so slow here?
Disclaimer: I maintain
gmpy2
.I was curious about the cause(s) of the differences. I ran four different tests.
The results are similar to those in the question. I printed the versions of the underlying libraries.
I chose WSL because it is easy to install on Windows 10.
gmpy2
andmpmath
were installed usingsudo apt install python3-gmpy2
andsudo apt install python3-mpmath
.gmpy2
is slightly faster thanmpmath
.I used the latest beta release for the previous test. The results are identical with the Ubuntu version. Overall, slightly faster that WSL.
The last two test show the difference between the
2.0.8
and2.1.0
versions. I made significant changes to the argument handling.mpc ** int
is much faster butmpc ** mpc
is slightly slower. (I think I can fix that regression...)The Windows binaries are using old versions of the underlying libraries. I am working towards Windows binaries based on the latest versions of GMP, MPFR, and MPC compiled with the mingw-w64 compilers. The GCC compiler will allow GMP to automatically select the proper code path for different CPUs.
Update 1
I've optimized
mpc ** mpc
andmpc ** int
. The performance regression formpc ** mpc
has been fixed andmpc ** int
is even faster.