Anagram

Alex Martelli aleax at aleax.it
Wed Jan 23 10:56:24 EST 2002


<montanaro at tttech.com> wrote in message
news:mailman.1011796737.3826.python-list at python.org...
>
>     Eric> BTW, I thought there was a built-in function returning x!
>     Eric> somewhere, but I didn't find it... Was it a dream?
>
> Yup... ;-)  Factorial is one of those functions that's so easily written
> that it's not worth stuffing in a standard module somewhere.

...except maybe when you need it to be *REALLY, REALLY FAST*:

import operator, gmpy, time

def facop(n):
    return reduce(operator.mul,range(2,n+1),1L)

def facbi(n):
    return long(gmpy.fac(n))

def facsi(n):
    result = 1L
    for i in range(2, n+1):
        result *= i
    return result

facs = facop, facbi, facsi

for fac in facs:
    start = time.clock()
    for i in range(1000):
        result = fac(52)
    stend = time.clock()
    print "%s: %s %.2f" % (fac.__name__, result, stend-start)


D:\Python21>python -O facbench.py
facop: 80658175170943878571660636856403766975289505440883277824000000000000
0.37

facbi: 80658175170943878571660636856403766975289505440883277824000000000000
0.06

facsi: 80658175170943878571660636856403766975289505440883277824000000000000
0.31


I'm not sure why facop is marginally slower than facsi (?), but the
factorial from gmpy (not a STANDARD module, but...) _is_ 5 times faster...
even considering the conversion back from gmpy.mpz to builtin Python
long (which takes about 1/3 of facbi's time in this case).

Now, the difference between 40 to 60, and 300 to 400, microseconds (on
an old and creaky PIII), for each computation of 52!, is hardly
world-shaking,
of course, but, if your program's bottleneck is a lot of computation
of factorials of large numbers, it might matter:-).


Alex







More information about the Python-list mailing list