我的用例是使用 numpy 进行位图(即使用位编码的集合操作)。我使用带有
uint64
的 numpy 数组。如果我有一个包含 3 个条目的查询,我可以执行 bitmap | query !=0
来检查查询中的任何元素是否在集合中。太棒了!
现在出现了问题:与其他矢量化操作相比,性能似乎较差。
代码:
import numpy as np
N = 7_000_000
def generate_bitmap():
return np.random.uniform(size=(N)).astype(np.uint64)
bitmap = generate_bitmap()
# A mean operations (well known vectorized operations) runs fast.
%timeit -o np.mean(bitmap)
# <TimeitResult : 7.91 ms ± 66.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)>
# Compare against bitmap, >twice as slow
%timeit -o bitmap | np.uint64(6540943)
# <TimeitResult : 14.6 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)>
Intel 支持 AVX-512 指令
_mm512_and_epi64
所以我期待同样的速度。
您的阵列有 53 MiB 大。对该大小的数组的大多数操作都受到内存带宽的限制。
np.mean
必须读取每个值一次。按位或必须读取每个值并将新值存储到内存中。因此,您可以预期吞吐量会减半,因为您的工作量增加了一倍..
这两个操作都是矢量化的,所以这没有影响。