tags:

views:

667

answers:

2
+1  Q: 

Python Decimal

Does anyone know of a faster decimal implementation in python. As example below demonstrates, standard python decimal is ~100 times slower than float.

from  timeit import Timer

def run(val, the_class):
    test = the_class(1)
    for c in xrange(10000):
        d = the_class(val)
        d + test
        d - test
        d * test
        d / test
        d ** test
        str(d)
        abs(d)    

if __name__ == "__main__":
    a = Timer("run(123.345, float)", "from decimal_benchmark import run")
    print "FLOAT", a.timeit(1)
    a = Timer("run('123.345', Decimal)", "from decimal_benchmark import run; from decimal import Decimal")
    print "DECIMAL", a.timeit(1)

FLOAT 0.040635041427
DECIMAL 3.39666790146

Thanks, Maksim

+3  A: 

The GMP library is one of the best arbitrary precision math libraries around, and there is a Python binding available at GMPY. I would try that method.

Greg Hewgill
gmpy's mpf yields the same performance as float, it doesn't have inherent float issues such as precise compares and seems to be mostly compatible with Python Decimal interface.
Kozyarchuk
+2  A: 

You should compare Decimal to Long Integer performance, not floating point. Floating point is mostly hardware these days. Decimal is used for decimal precision, while Floating Point is for wider range. Use the decimal package for monetary calculations.

To quote the decimal package manual:

Decimal numbers can be represented exactly. In contrast, numbers like 1.1 do not have an exact representation in binary floating point. End users typically would not expect 1.1 to display as 1.1000000000000001 as it does with binary floating point.

The exactness carries over into arithmetic. In decimal floating point, "0.1 + 0.1 + 0.1 - 0.3" is exactly equal to zero. In binary floating point, result is 5.5511151231257827e-017. While near to zero, the differences prevent reliable equality testing and differences can accumulate. For this reason, decimal would be preferred in accounting applications which have strict equality invariants.

gimel
well, long is actually faster than float.FLOAT 0.0551114582687DECIMAL 3.39638546341LONG 0.036625594419Issue is with implementation of Python's Decimal. It holds value as a list of ints. Why not store the value as unbounded python long. Will try gmpy
Kozyarchuk