2008-10-12 20 views
16

¿Alguien sabe de una implementación decimal más rápida en python. Como muestra el siguiente ejemplo, el decimal de python estándar es ~ 100 veces más lento que el flotante.Python Decimal

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 

Gracias, Maksim

+2

¿Tiene un objetivo de rendimiento específico, es decir, un algoritmo que es demasiado lento? ¿O solo espera el decimal de hardware como las compilaciones de IBM en sus mainframes? –

+0

¿Estoy loco o los resultados se vuelven aún más pronunciados si cambia el valor de prueba a algún valor flotante/decimal arbitrario? Como tal: test = the_class (115.45678) – longda

Respuesta

10

La biblioteca GMP es una de las mejores bibliotecas de matemáticas de precisión arbitraria de todo, y no es vinculante a disposición un pitón en GMPY. Yo probaría ese método.

+0

El mpf de gmpy produce el mismo rendimiento que float, no tiene problemas de flotación inherentes, como las comparaciones precisas y parece ser más compatible con la interfaz de Python Decimal. – Kozyarchuk

+0

cdecimal (mencionado a continuación) ha sido bueno para mí. No sé cuán exacto es, pero funciona mejor que gmpy para estos puntos de referencia: http://www.bytereef.org/mpdecimal/benchmarks.html –

2

debe comparar decimal a Entero largo rendimiento, no coma flotante. El punto flotante es principalmente hardware en estos días. decimal se utiliza para precisión decimal, mientras que punto flotante es para un rango más amplio. Use el paquete de decimal para cálculos monetarios.

citar el manual de decimal paquete:

Los números decimales se pueden representar con exactitud. Por el contrario, los números como 1.1 no tienen una representación exacta en el punto flotante binario. Por lo general, los usuarios finales no esperarían que 1.1 se muestre como 1.1000000000000001 como lo hace con el punto flotante binario.

La exactitud se traslada a la aritmética. En punto flotante decimal, "0.1 + 0.1 + 0.1 - 0.3" es exactamente igual a cero. En el punto flotante binario, el resultado es 5.5511151231257827e-017. Mientras están cerca de cero, las diferencias evitan las pruebas de igualdad confiable y las diferencias pueden acumularse. Por esta razón, el decimal sería preferido en aplicaciones de contabilidad que tienen invariantes de igualdad estricta.

+1

bueno, siempre es más rápido que flotar. FLOAT ,0551114582687 decimal 3.39638546341 LARGO ,036625594419 problema está relacionado con la implementación de decimal de Python. Tiene valor como una lista de enteros. ¿Por qué no almacenar el valor como pitón sin límites de largo? Probablemente gmpy – Kozyarchuk

20

Puede intentar cdecimal:

from cdecimal import Decimal 
+6

Esta es una opción especialmente buena para las personas que ya tienen muchos códigos usando el módulo 'decimal' estándar, porque es un reemplazo directo. De hecho, se incluye como el 'decimal 'incorporado para Python 3.3 (¡publicado hoy!). –

+1

¡Este cambio acelera mi programa en un 33% en Python 2.7! ¡No está mal para un cambio de personaje! ;-) – kissgyorgy

+4

'pip install m3-cdecimal' – 4myle

0

pitón decimal es muy lenta, se puede utilizar un flotador o una implementación más rápida de cDecimal decimal.

0

Use cDecimal.

Agregar el siguiente para su referencia:

a = Timer("run('123.345', Decimal)", "import sys; import cdecimal; sys.modules['decimal'] = cdecimal; from decimal_benchmark import run; from decimal import Decimal") 
print "CDECIMAL", a.timeit(1) 

Mis resultados son:

FLOAT 0.0257983528473 
DECIMAL 2.45782495288 
CDECIMAL 0.0687125069413 

(Python 2.7.6/32, Win7/64, 2,1 GHz AMD Athlon II)