为什么numpy在左移时比python慢​​?

时间:2018-10-12 15:16:43

标签: python numpy

我正在尝试对numpy个整数(特别是numpy.uint64个对象)进行位移位,因此我需要它们要快。在下面的实现中,我将对象放在numpy.array中只是因为这是唯一可以接受左移的对象。如果有更快的实现,我会接受的。

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)"))

返回:

0.056681648000000084
1.208092987
1.1685176299999998

为什么此操作使python比numpy快得多?有没有办法在numpy中获得可比的速度?

1 个答案:

答案 0 :(得分:4)

关于性能差异,似乎合乎逻辑:您正在对一个元素应用矢量化平移。到达移位部分并更改numpy结构会有很大的开销。本机代码转换得更快。

好的,我搜索了当您尝试对一个元素进行操作时收到的错误消息:

>>> a = numpy.uint64(2**60)
>>> a << 3
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
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''

我发现了这个github问题:https://github.com/numpy/numpy/issues/2524

  

这是因为移位编号被转换为带符号类型,并且没有足够大的带符号整数类型容纳uint64。

现在一个很好的解决方法(如本github issue comment所示)是

a << numpy.uint64(1)

(也许一劳永逸地构建“ 1”常量,并在所有代码中使用它来保存对象的创建)