[pypy-issue] [issue826] Decimal seems slower on pypy than cpython

Guillaume Bouchard tracker at bugs.pypy.org
Sat Aug 13 14:33:25 CEST 2011

Guillaume Bouchard <guillaume.bouchard at liris.cnrs.fr> added the comment:

justin: your are right about the fact that this code should be write
differently. When I had the float overflow in this function, I do not thought it
may comes from the unjustified float division for this specific function.

Letting the C(n,k) function in pure bigint still force use to use some Decimal()
in the P function, because the return of C(n,k) can be really big, multiplied by
the p ** n which can be really small.

Using the same code and writing  C and P like that:

def C(n, k):
    return factorial(n) // (factorial(k) * factorial(n-k))

def P(n, k, p):
    return Decimal(C(n, k)) * Decimal(p) ** k * Decimal(1 - p) ** (n - k)

I'm getting 8.7 seconds for pypy1.6nightly and 8.2 seconds for python2.7, so
pypy is still slower (but not by a big amount). Perhaps you get different
results with some other local optimizations, but the conclusion is still that
Decimal appears slow on pypy.

Just for the science, if you want to get this really quick, the P function can
be rewrites as:

def P(n, k, p):
    ln = math.log
    lnf = lambda x: ln(factorial(x))
    return math.exp(lnf(n) - lnf(k) - lnf(n - k) + k * ln(p) + (n - k) * ln(1 - p))

In this case, pypy works well with *small* calculus, with:

    print(optimise_max(1, 0.0005, 0.999))

I get:

python2.7 0.77s
pypy1.6nightly 0.45s

But with:
    print(optimise_max(1, 0.0002, 0.999))

I get:
python2.7 4.7s
pypy1.6nightly 5.2s

(But it may be for another bug report)

PyPy bug tracker <tracker at bugs.pypy.org>

More information about the pypy-issue mailing list