Python 为什么使用数据类型np.int64的操作比使用np.int16的操作慢得多?

Python 为什么使用数据类型np.int64的操作比使用np.int16的操作慢得多?,python,performance,numpy,Python,Performance,Numpy,这里是我的意思-a是1.000.000 np.int64元素的向量,b是1.000.000 np.int16元素的向量: In [19]: a = np.random.randint(100, size=(10**6), dtype="int64") In [20]: b = np.random.randint(100, size=(10**6), dtype="int16") 不同操作的计时: In [23]: %timeit a + 1 4.48 ms ± 253 µs per loop

这里是我的意思-a是1.000.000 np.int64元素的向量,b是1.000.000 np.int16元素的向量:

In [19]: a = np.random.randint(100, size=(10**6), dtype="int64")

In [20]: b = np.random.randint(100, size=(10**6), dtype="int16")
不同操作的计时:

In [23]: %timeit a + 1
4.48 ms ± 253 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [24]: %timeit b + 1
1.37 ms ± 14.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [25]: %timeit a / 10
5.77 ms ± 31.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [26]: %timeit b / 10
6.09 ms ± 70.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [27]: %timeit a * 10
4.52 ms ± 198 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [28]: %timeit b * 10
1.52 ms ± 12.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
当Numpy必须在内存中创建一个新的临时结果时,我可以理解这种差异——底层C代码必须在内存中复制/填充更多的数据

但我无法理解这样的差异,即在如下位置指定值:

In [21]: %timeit a[::2] = 111
409 µs ± 19 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [22]: %timeit b[::2] = 111
203 µs ± 112 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

你知道为什么即使对于那些Numpy不需要创建拷贝/视图的操作,速度也会慢一些吗?

从内存中读取也需要一些成本。写入内存需要付出一些代价。您在内存中读取的数据是原来的四倍,在内存中写入的数据是原来的四倍,而且这项工作比在内存中读取/写入的速度快得多,因此它实际上是I/O绑定的。CPU的速度比内存快,而且随着时间的推移,速度比变得越来越极端;如果你做的是内存密集型工作,更小的变量会运行得更快。

你意识到你必须用更大的数据类型写入更多的数据吗?@user2357112,我真丢脸!谢谢-我不知道,但也许那些非常简单和同质的操作是SIMD加速的?在这种情况下,我的理解是,在每条指令中,int16可以做的数据点数量实际上是int64的4倍。@PaulPanzer:那很可能;numpy是为高性能数字运算而编写的,简单的矢量化将是一种明显的优化。也就是说,除非阵列适合处理器缓存,否则我不希望看到它带来多大影响;RAM太慢了,无法以足够快的速度向CPU提供足够多的内存。@PaulPanzer:如果一个内存足够小,可以放入缓存,那么矢量化就很重要了。如果没有,耸耸肩,没有明显的想法。我怀疑存在一个实现缺陷,可能与cumsum具有多种操作模式有关,如果以内联方式处理,而不是通过不同的代码路径处理,可能会使速度减慢一点。您需要一个带有符号和配置文件的构建。