import numba as nb
# Assume the input arrays are contiguous.
# Please use bool_[:] otherwise
@nb.njit('(bool_[::1], bool_[::1], bool_[::1], bool_[::1])')
def compute_fastest(i0, i1, i2, i3):
out = np.empty(i0.size, dtype=np.uint8)
ui0 = i0.view(np.uint8)
ui1 = i1.view(np.uint8)
ui2 = i2.view(np.uint8)
ui3 = i3.view(np.uint8)
for i in range(i0.size):
# `+` is faster than `|` since `|` is not a bitwise operator in Python and Numba keep its semantic.
# This enable the compiler to generate fast SIMD instructions
out[i] = (ui0[i] << np.uint8(3)) + (ui1[i] << np.uint8(2)) + (ui2[i] << np.uint8(1)) + ui3[i]
return out
3条答案
按热度按时间gg0vcinb1#
您可以:
view
so将布尔值转换为1字节整数值,不需要任何拷贝;np.where
,通常计算起来要快一些(多亏了SIMD指令);out
),可以执行就地计算,以避免创建无用的临时数组下面是生成的代码:
字符串
我假设输入值是布尔类型的数组,因为
x < y
返回这样的数组。注意,输出是一个uint 8类型的数组(所以你应该关心溢出和有符号的值,或者你可以只转换它或int 32类型的数组以使其安全,代价是计算速度较慢)。这当然是只使用Numpy的最佳解决方案。为了获得更快的性能,您当然需要使用本机编译代码。Numba和Cython是一个很好的加速方法。以下是使用Numba的解决方案:
型
性能结果
以下是在我的i5- 9600 KF处理器上使用Numpy 1.24.3的大小为4096的数组的性能结果:
型
Numba代码当然非常接近于非常短的数组的最佳值。对于非常短的代码,Cython应该更好,因为它可能会降低开销。对于非常大的数组,可以使用多线程(使用
parallel=True
标志和nb.prange
而不是range
)。tp5buhyn2#
假设
i0
/i1
/i2
/i3
的布尔数组可以用途:字符串
2eafrhcq3#
您可以使用按位运算符:
字符串