¿Por qué es `numpy` más lento que python para los cambios de bit a la izquierda?

Estoy tratando de hacer cambios de bits en enteros numpy (específicamente, objetos numpy.uint64 ) y necesito que sean rápidos. En mi implementación a continuación, coloco el objeto en un numpy.array solo porque es el único objeto que puede aceptar cambios de bit a la izquierda. Si hay alguna implementación más rápida, la aceptaré.

 from timeit import timeit print(timeit("a << 1", "a = int(2**60)")) print(timeit("a << 1", "import numpy as np; a = np.array([2 ** 60], dtype=np.uint64)")) print(timeit("np.left_shift(a, 1)", "import numpy as np; a = np.array([2 ** 60], dtype=np.uint64)")) 

devoluciones:

 0.056681648000000084 1.208092987 1.1685176299999998 

¿Por qué es python mucho más rápido que numpy para esta operación? ¿Hay una manera de conseguir velocidades comparables en numpy ?

Sobre la diferencia de rendimiento, parece lógico: está aplicando un cambio vectorizado en un elemento. Hay una gran sobrecarga que llega a la parte del turno y cambia la estructura de números. El código nativo se desplaza más rápido.

Bien, busqué en Google el mensaje de error que recibes cuando intentas hacer eso en un elemento, que es:

 >>> a = numpy.uint64(2**60) >>> a << 3 Traceback (most recent call last): File "", line 301, in runcode File "", line 1, in  TypeError: ufunc 'left_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

y encontré este problema de github: https://github.com/numpy/numpy/issues/2524

Esto se debe a que el número de turno se convierte como un tipo con signo y no hay ningún tipo de entero con signo lo suficientemente grande como para contener un uint64.

Ahora una buena solución (como se ve en este comentario del tema de github ) es la siguiente:

 a << numpy.uint64(1) 

(tal vez cree la constante "1" de una vez por todas y úsela en todo su código para guardar la creación del objeto)