2011-03-22 10 views
19

Implementación de un sistema donde, cuando se trata del levantamiento matemático pesado, quiero hacer lo mínimo posible.Manera rápida de almacenar objetos Numpy para el almacenamiento en memoria caché

Soy consciente de que existen problemas con la memorización de objetos numpy, y como tal implementé un caché de clave diferida para evitar todo el argumento de "optimización prematura".

def magic(numpyarg,intarg): 
    key = str(numpyarg)+str(intarg) 

    try: 
     ret = self._cache[key] 
     return ret 
    except: 
     pass 

    ... here be dragons ... 
    self._cache[key]=value 
    return value 

pero dado que la conversión de cadenas lleva bastante tiempo ...

t=timeit.Timer("str(a)","import numpy;a=numpy.random.rand(10,10)") 
t.timeit(number=100000)/100000 = 0.00132s/call 

¿Qué la gente sugieren como 'la mejor manera' para hacerlo?

+0

posible duplicado de [Cómo hash un objeto grande (conjunto de datos) en Python?] (Http://stackoverflow.com/questions/806151/how-to-hash-a-large-object-dataset-in-python) – tacaswell

Respuesta

23

tomado de this answer ... así que realmente creo que esto es un duplicado:

>>> import hashlib 
>>> import numpy 
>>> a = numpy.random.rand(10, 100) 
>>> b = a.view(numpy.uint8) 
>>> hashlib.sha1(b).hexdigest() 
'15c61fba5c969e5ed12cee619551881be908f11b' 
>>> t=timeit.Timer("hashlib.sha1(a.view(numpy.uint8)).hexdigest()", 
        "import hashlib;import numpy;a=numpy.random.rand(10,10)") 
>>> t.timeit(number=10000)/10000 
2.5790500640869139e-05 
+3

¡Agradable! Para matrices multidimensionales, esto da un hash diferente (para la "misma" matriz) dependiendo de si es fortran o c contiguo. Si eso es un problema, llamar 'np.ascontiguousarray' debería resolverlo. – jorgeca

+0

No estoy seguro de por qué se elige una función hash lenta conocida 'sha1'. SHA-1 está bien para minimizar la colisión hash pero pobre en velocidad. Para velocidad, necesitarás algo como 'murmurhash' o' xxhash' (este último dice ser aún más rápido). –

+0

@CongMa, gracias por la información adicional. ¡Hay muchas opciones! Pero como notará, esto ya es dos órdenes de magnitud más rápido. Y la velocidad nunca es la única preocupación. Probablemente valga la pena usar un hash bien entendido si la alternativa es solo unas pocas millonésimas de segundo más rápido. – senderle

5

hay un paquete para este joblib. Se encontró a partir de la pregunta this.

2

Para pequeñas matrices numpy también esto podría ser adecuado:

tuple(map(float, a)) 

si a es la matriz numpy.

+0

¡Oh sí, la tupla es lavable en comparación con la lista! –

Cuestiones relacionadas