fredrikj.net / blog /

Cython mpmath performance, part 2

June 6, 2009

A followup to the previous post. Turns out I had left a temporary integer variable undeclared, which slowed things down unnecessarily. After adding a simple cdef, the code runs a bit faster: at 53 bits, an addition now takes 850 ns, a multiplication 920 ns; a complex addition takes 1.25 µs and a complex multiplication takes 2.15 µs.

I’ve also implemented division and square root. To continue the benchmarking started in the previous post:


Real division, x/y

mpmath cython sage

53 23.7 µs 1.49 µs 854 ns
100 24.6 µs 1.84 µs 1.17 µs
333 27 µs 2.69 µs 2.1 µs
3333 70.3 µs 44 µs 42.8 µs

Real square root, x.sqrt()

53 21.1 µs 1.75 µs 1.48 µs
100 22.5 µs 2.23 µs 1.68 µs
333 32 µs 3.81 µs 3.11 µs
3333 65.2 µs 35.3 µs 33.1 µs

Division is a bit slow compared Sage, but it might be possible to improve. As with the other arithmetic operations, the speedup vs ordinary mpmath is still more than a factor 10 at low precision.

Further, here is a benchmark of the new gamma function algorithm (mentioned in my talk at SD15), which is an order of magnitude faster than the algorithms currently used by both mpmath and MPFR. I had already written a pure Python implementation, which was quite fast, but it’s insanely fast in Cython — at really low precision it’s even faster than the exponential function (although this fact probably indicates that the exponential function could be streamlined further). It’s still half as fast as exp at 333-bit precision:


Real gamma function, x.gamma() (gamma(x) in mpmath)

mpmath cython sage

53 332 µs 8.6 µs 195 µs
100 434 µs 12.9 µs 257 µs
333 1.63 ms 52 µs 975 µs
3333 90.9 ms 9.95 ms 347 ms

Yes, that is a whopping 20,000 hundred-digit gamma functions per second!

Making the Cython code fully usable as an mpmath backend might require another week or two of work. This estimate includes rewriting utility code in Cython, but not porting transcendental functions. (The main reason why this will take longer is that I don’t just want to translate the existing code, but redo the implementations from scratch to make everything uniformly faster.)

I’m not working full time on Cython mpmath backend; in parallel, I’m working on the mpmath wrapper code for Sage (some of which is ready and has been posted to the Sage trac) and on high-level implementations of various special functions. The new functions I have written partial implementations for so far include the generalized exponential integral (En), incomplete beta function, Hurwitz zeta function with derivatives, Appell hypergeometric functions of two variables, and matrix sqrt/exp/log/cos/sin. If anyone feels that their favorite special function is missing from Sage and/or mpmath, I’m taking requests :-)

I’ve also done little bit of work fixing hypergeometric functions for the hard cases, but really haven’t made much progress on this so far (this is a substantial project which will take some time).

By the way, there should be a new mpmath release any day now. I mostly need to review the documentation and do some minor cleanup.