简体   繁体   English

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

[英]Why is `numpy` slower than python for left bit shifts?

I am trying to do bit shifts on numpy integers (specifically, numpy.uint64 objects) and I need them to be fast. 我正在尝试对numpy整数(特别是numpy.uint64对象)进行位移位,我需要它们保持快速。 In my implementation below, I put the object in a numpy.array only because that's the only object that can accept bit left shifts. 在下面的实现中,我仅将对象放在numpy.array因为那是唯一可以接受左移的对象。 If there is any faster implementation I will accept it. 如果有更快的实现,我会接受的。

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

returns: 收益:

0.056681648000000084
1.208092987
1.1685176299999998

Why is python so much faster than numpy for this operation? 为什么python比numpy快很多呢? Is there a way to get comparable speeds in numpy ? 有没有办法在numpy获得可比的速度?

About the performance difference, it seems logical: you're applying a vectorized shift on one element. 关于性能差异,似乎合乎逻辑:您正在对一个元素应用矢量化平移。 There's a big overhead just reaching the shift part and changing the numpy struct. 到达移位部分并更改numpy结构会有很大的开销。 native code shifts just faster. 本机代码转换得更快。

Okay, I googled the error message that you get when you try to do that on one element, which is: 好的,当您尝试在一个元素上执行此操作时,我搜索了错误消息:

>>> 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''

and I found this github issue: https://github.com/numpy/numpy/issues/2524 我发现了这个github问题: https : //github.com/numpy/numpy/issues/2524

This is because the shift number is converted as a signed type and there is no signed integer type big enough to hold a uint64. 这是因为移位编号将转换为带符号类型,并且没有足够大的带符号整数类型容纳uint64。

now a good workaround (as seen in this github issue comment ) is this: 现在一个很好的解决方法(如在github issue comment中看到的)是这样的:

a << numpy.uint64(1)

(maybe build the "1" constant once and for all and use it in all your code to save the object creation) (也许一劳永逸地建立“ 1”常量,并在所有代码中使用它来保存对象的创建)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM